`

Trail: The Reflection API1

 
阅读更多

所有的变量类型或者是一个引用,或者是原始类型, 字符串,类,枚举,数组,接口,注解,都是引用

对所有的对象,JVM都会立即生产一个java.lang.Class的不可变实例,包含各种方法来检测这个对象的运行时属性

Class也可以创建新类和新对象,也是所有反射API的主入口

 

java.lang.reflect 包中的所有类都没有public的构造,只能调用Class的相关方法获得他们的实例

1.如果存在一个实例对象,最简单的方法就是调用Object.getClass()来获得Class对象

2.如果没有实例,只有一个类型,可以使用XX.class,当然更适合于原始类型.class,也适用于多重数组,包括void类型

 

 3.Class.forName("com.duke.MyLocaleServiceProvider");

一般用于全名,是Class类的static方法,可以直接用,不过原始类型只能用第二种

 

 

Class cDoubleArray = Class.forName("[D");//类似于double[].class

Class cStringArray = Class.forName("[[Ljava.lang.String;");//类似于String[][].class

4.每个包装类包括Void,都有个TYPE字段,也会获得Class对象

 

5.有的方法也会返回另一个Class对象,不过前提是已经有了一个Class对象

 

Class.getSuperclass()//父类
Class.getEnclosingClass()//外部类
Class.getClasses()//返回所有内部类,枚举,接口,包括继承过来的

Character也有几个方法(略)

 

 

XX.getDeclaringClass()//可以是Class,Field,Method,Constractor

当然匿名内部类是没有名字的,名字是null

 

 

每个类和成员都会有不同的修饰符(modifiers),包括注解,java.lang.reflect.Modifier

但不是所有注解都能通过反射得到

 

getDeclaredField()会返回包括private字段,但不包括继承的

getField()会返回public的字段,也包括继承的

字段和方法都是这样,但构造是没有继承这一说

 

 

private static void printMembers(Member[] mbrs, String s) {//这是一个通用的成员打印方法
	out.format("%s:%n", s);
	for (Member mbr : mbrs) {
	    if (mbr instanceof Field)
		out.format("  %s%n", ((Field)mbr).toGenericString());
	    else if (mbr instanceof Constructor)
		out.format("  %s%n", ((Constructor)mbr).toGenericString());
	    else if (mbr instanceof Method)
		out.format("  %s%n", ((Method)mbr).toGenericString());
	}
	if (mbrs.length == 0)
	    out.format("  -- No %s --%n", s);
	out.format("%n");
    }

 

 

 

Class.newInstance()可以用来实例化一个对象,但调用的是无参的那个构造,没有无参构造会异常

所以应该用Constructor.newInstance(),可以传入参数

 

 

reflect包中有个Member接口,代表类中的成员,

实现它的类有Field,Method,和Constructor

按照最新规范,继承来的东西也属于成员,而构造并不属于成员,reflect包的这个实现是比较特殊的

 

另外三个类的父类是AccessibleObject 类,里面有方法setAccessible(true),和static方法

还有,反射里,对字段重新赋值的话,是没有自动装箱拆箱的

 

Field类里的setXX方法会降低很多性能,因为涉及到很多操作,不过在JRE看来效果是一样的

在没有setAccessible(true)之前,final的字段是不能修改的,但有了权限后的确可以修改

public field 都包括:

这个类中定义的

这个类的父类中定义的

这个类实现的接口中定义的

这个类实现的接口所继承的接口中的

 

 

 public static void main(String... args) {//这样写跟以前是一样的,数组完全可以取代可变长度参数列表

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics