转载请标明出处: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.People
class java.lang.Class
class 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(“类完全限定名”)