本系列翻译自Oracle官方教程,半翻译,半读后感性质。文末会附上原文链接。
上一篇的最后提到,Class是所有反射API的entry point。坑爹的是,reflect包下所有的类都没有公共的构造方法,意思是你new不出来啊喂。但是通过一个类的实例比如"foo".getClass(),Class的名字比如“java.lang.String”,类型比如Double.TYPE,或者类本身比如String.class这4种方法还是可以得到一个Class的实例。
Object.getClass()
如果能拿到某个类的实例,就可以调用 Object 的getClass()方法获得Class的实例。除了之前提到的字符串的例子,还有4类场景。
// 场景1:
// 返回java.io.Console的类实例
Class c = System.console().getClass();
// 场景2:枚举
// 返回E的类实例
enum E { A, B }
Class c = A.getClass()
// 场景3:数组
// 返回一个数组的类实例,其元素的类型是byte
byte[] bytes = new byte[1024];
Class c = bytes.getClass();
// 场景4:接口
// 返回java.util.HashSet的类实例
Set<String> s = new HashSet<String>();
Class c = s.getClass();
其中第一个例子没理解跟"foo"有什么区别。最后一个例子,想表达的应该是,返回的不是编译时类型(Set)而是运行时类型(HashSet)的意思吧。
(这几类,平时都没有怎么用到过)
.class语法
对于原始数据类型,直接调用getClass()会编译报错。通过下面的写法可以获得类实例。
Class c = boolean.class;
Class.forName()
通过全限定名获得类实例。限制是不能用于原始数据类型。
除了最常见的写法还有下面这样作用于数组的。可以理解为一个“[”代表一维数组。
// 等效于double[].class
Class cDoubleArray = Class.forName("[D");
// 等效于String[][].class
Class cStringArray = Class.forName("[[Ljava.lang.String;");
TYPE字段
用于原始类型的包装类或者Void。这些类都有一个名为TYPE的字段。
// 等效于double.class
Class c = Double.TYPE;
(完全没有用过)
网友评论