【java】元类

来源:互联网 发布:淘宝天猫怎么申请 编辑:程序博客网 时间:2024/05/21 09:49

转载请标明出处:http://blog.csdn.net/u012250875/article/details/78087921

一、什么是元类?

编程中有个概念叫元类(meta-class),元类的概念在Java,Python和Object-C中都有,那什么是元类?为什么会有元类的概念?

首先上一句话:万物皆对象!

我们知道在面向对象的编程思想中经常听到一句话:万物皆对象!在面向对象的思想中,还有一组与哲学相关的概念:抽象和具体。所谓抽象是指对事物的泛化,是对具体的一种分析得到的东西,而具体指的是抽象中的一个实在具体,有一句比较绕但高度概括抽象与具体二者关系的话:抽象是具体的抽象,具体是抽象的具体,这句话本身就是一种抽象并且具有自解释性(别打我,这句话确实绕,但这又是解释抽象与具体最恰当的,最合适的一句话,没有之一!>_<)。说到这,这组哲学词汇和“类与对象”这个计算机词汇有什么关系呢?“类和对象”的概念刚好就是“抽象与具体”的这个概念,并且是“抽象与具体”这个概念的一个具体。我们说“你”,“我”,“小明”,“王二小”等等这些都是人,抽象的结果就有了“人类”这个类。而“你”,“我”,“小明”这些人是人类这个类的实例,具体。我们前面又说“万物皆对象”,由此我们会很自然的推导出:“你”,“我”,“小明”,“王二小”都是对象,再继续推导,突然发现“人类”这个类也是对象,这个时候可能会懵逼了,“人类”不是类么?怎么又成了对象?确实“人类”是类,但是,别忘了万物皆对象啊。存在“人类”,“犬类”,“鸟类”这些类的概念泛化之后是什么?那么我们对类的这个概念进行泛化抽象之后它是属于哪个类?这个时候元类这个概念产生了。“人类”是“元类”的一个对象,你可能会说,如此依据万物皆对象这个原则,如此我能够说“元类”这个事物也能看成是某个类的一个对象。那么“元类”这个对象所属的类是什么?当然还是“元类”,我们终于找到了“上帝”,对,这个类中的上帝就是“元类”,已经具有自描述性了。

下面我们用java来看一看java语言本身是怎么描述这个问题的。

public class Test {    public static void main(String[] args) {        People xiaoming = new People();        System.out.println(xiaoming.getClass());//小明这个对象为People类的一个对象        System.out.println(xiaoming.getClass().getClass());//People这个对象为Class元类的一个对象        System.out.println(xiaoming.getClass().getClass().getClass());//Class这个对象为Class元类的一个对象    }}
class pyf.java.test.Peopleclass java.lang.Classclass java.lang.Class

由此可看出:在java中,Class表示元类,实例.getClass表示获取实例所属的类。

二、怎么获取类的元类型

那么java中怎么获取一个类的元类呢?大概有下面这么几种方法:
1)类型.class
这种方式很直接,引用类型可以使用该方式来获取元类,基本类型也能通过该方式获取元类

Class c1 = int.class;Class c2 = InputStream.class;

2)实例.getClass()
这种方式是通过一个实例调用基类Object的方法

Person xiaoming = new Person();Class<Person> cls = xiaoming.getClass();

Object的getClass方法原型如下:

public final native Class<?> getClass();

3)Class.forName(className)
这种方式,className指的是采用类的完全限定名(完整的包名+类名,如果是内部类,则是包名+类名$内部类名),使用这种方式很灵活,因为参数是字符串,可以结合配置文件来达到动态效果。

//假设类在pyf.java.demo包下,类名为Person,则获取方法如下Class<?> cls = Class.forName("pyf.java.demo.Person");

Class.forName方式对于玩过jdbc的小伙伴应该很熟悉了,在加载jdbc驱动时就使用了该种方式

//DRIVER为配置的jdbc驱动名称static {    try {        Class.forName(DRIVER);    } catch (ClassNotFoundException e) {        e.printStackTrace();    }}

使用场景
获取元类的场景一般是在用到反射时,因为通过元类能拿到类本身的信息,如类的成员变量,构造方法,方法等,这为动态化编程带来了方便,这也是很多框架的基础

三、总结:

1.万物皆对象
2.抽象是具体的抽象,具体是抽象的具体
3.实例,类,元类的关系:具体,抽象,再抽象
4.元类的三种获取方式 类型.class,实例.getClass,Class.forName(“类完全限定名”)

原创粉丝点击