1 、反射的基石----->Class 类
2 、得到各个字节码对应的实例对象(Class 类型)
- 类名 . Class ,例如: System. class
- 对象名 .getClass( ) ,例如: new Date( ).getClass( )
- Class.forName ( “类名” )
3 、九个预定义Class 实例对象
- 用 Class.isPrimitive() 查看是否是原始类型,如 String. class .isPrimitive() //false
- Int. class == Integer.Type; //true
4 、数组类型的Class 实例对象,用 Class.isArray() 判断,例如int[]. class .isArray() , 返回true
5 、只要在源程序程序中出现的类型,都有各自的Class 实例对象,例如: void . class , int[]. class
6 、反射就是把Java 类中的各种成分映射成相应的Java 类
7 、Constructor 类
- Constructor 类代表某个类中的构造方法
- 得到某个类的构造方法,
例如 Constructor[] cons = Class.forName( “java.lang.String” ).getConstructor();
- 得到某一个构造方法: Constructor constructor =
Class.forName( “java.lang.String” ).getConstructor(StringBuffer. class ) // 参数类型
- 创建实例对象:
通常方式: String str= new String(new StringBuffer( “abc” ));
反射方式: String str = (String)constructor.newInstance(new StringBuffer( “abc” ));
- Class.newInstance( ) 省去了调用无参的 Constructor.newInstance( );
该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。该方法的内部代码用到了缓存机制来保持默认的构造方法的实例对象。
8 、Filed 类
- Filed 类代表某个类中的一个成员变量
- 实例代码
ReflectPoint rp = new ReflectPoint(3, 5);
Field filedY = rp.getClass().getField( "y" ); //public int y;
//filedY 是 Y 的定义,而不是具体的 Y 的对象,要用它的 get ( “ 对象 ” )方法获得
System. out .println(filedY.get(rp1));
// 暴力反射
Field fieldX = rp.getClass().getDeclaredField( "x" ); //private int x;
fieldX.setAccessible( true ); // 打开私有类型变量的访问权限
System. out .println(fieldX.get(rp1));
- 替换任意一个对象中的所有String 类型的成员变量所对应的字符串中的b 改成a
//public String str1=”ball”,str2=”basketball”
private static void changeStringValue(Object obj) throws Exception {
Field[] fields = obj.getClass().getFields();
for (Field field : fields) {
// if(field.getType().equals(String.class))
if (field.getType() == String. class ) {
String oldValue = (String) field.get(obj);
String newValue = oldValue.replace( 'b' , 'a' );
field.set(obj, newValue);
}
}
}
9 、Method 类
- Method 类代表某个类中的一个成员方法
- 得到类中的某一个方法
String str1 = “abc”;
Method methodCharAt = String. class .getMethod( "charAt" , int . class );
- 调用方法:
普通方式: System.out.println(str1.charAt(1));
反射方式: System. out .println(methodCharAt.invoke(str1, 1));
- 如果str1 位置为null ,该方法为静态方法
- Jdk1.4 和jdk1.5 的invoke 方法的区别
System. out .println(methodCharAt.invoke(str1, 1)); //1.5
System. out .println(methodCharAt.invoke(str1, new Object[]{2})); //1.4 需要传入数组
- 调用传递过来的某个类的main 方法
String startingClassName = args[0]; //args[0]=package.TestArguments
Method mainMethod = Class.forName (startingClassName).
getMethod( "main" , String[]. class );
//mainMethod.invoke(null, new Object[]{new String[]{"111","222","333"}});
mainMethod.invoke( null , (Object) new String[]{ "111" , "222" , "333" });
//jdk1.5 为兼容 1.4 以前版本,对传入的参数都作为一个 Object[] ,并对其拆包
*******************************************************************
class TestArguments {
public static void main(String[] args) {
for (String arg: args) {
System. out .println(arg);
}
}
}
10 、数组反射
- 数组的== ,数组的父类
int [] a1 = new int [3];
int [] a2 = new int [4];
String[] a3 = new String[]{ "a" , "b" , "c" };
System. out .println(a1.getClass().getName()); //[I
- 具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class 实例对象
System. out .println(a1.getClass() == a2.getClass()); //true
- 代表数组的Class 实例对象的getSuperClass( ) 方法返回的父类为Object 类对应的Class
System. out .println(a1.getClass().getSuperclass().getName());
//java.lang.Object
- 基本类型的一维数组可以被当做Object 类型使用,不能当做Object[] 类型使用;
- 非基本类型的一维数组即可当Object 类型,又可当做Object[] 类型使用
Object aObj1 = a1; // 没有报错
Object aObj2 = a3; // 没有报错
Object[] aObj3 = a3; // 没有报错
//Object[] aObj4 = a1;// 编译时报错
System. out .println(a1); //[I@14318bb
System. out .println(a3); //[Ljava.lang.String;@ca0b6
- Arrays.asList() 方法处理int[] 和String[] 时的差异
System. out .println(Arrays.asList (a1)); //[[I@14318bb]
System. out .println(Arrays.asList (a3)); //[a, b, c]
//1.4asList(Object[] obj) 1.5asList(T… a) 使用了泛型
- Arrays 工具类用于完成对数组的反射操作