1.1,Class类:反射的基石
1,Class:指的是Java程序中的各个Java类是属于同一类事物,都是Java程序的类,这些类称为Class。例如人对应的是Person类,Java类对应的就是Class。Class是Java程序中各个Java类的总称;它是反射的基石,通过Class类来使用反射。
1.2,Class对象的获取
1,通过类名.class获取
Class clazz = String.class;
2,通过对象的getClass方法进行获取。
String str = new String(“abc”);
Class clazz = str.getClass();
3,通过Class.forName(“类名的全名”)
Class clazz =Class.forName(“java.lang.String”);
示例:
package in.cast;
public class ReflectTest {
/**
* @param args
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws ClassNotFoundException {
//获取Class对象
String str = new String("abc");
Class clazz1 = String.class;
Class clazz2 = str.getClass();
Class clazz3 =Class.forName("java.lang.String");
System.out.println(clazz1 == clazz2);//true
System.out.println(clazz1 == clazz3);//true
}
}
1.3,九个预定义的Class
1,包括八种基本类型(byte、short、int、long、float、double、char、boolean)
的字节码对象和一种返回值为void类型的void.class。
2.1,反射
1,反射就是把Java类中的各种成分映射成相应的java类。例如,一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示。
就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是Field、Method、Contructor、Package等等。
3.1,Constructor类
1,Constructor类代表某个类的构造方法。
2,获取某个类的所有的构造:
Constructor constructors[] = Class.forName(“java.lang.String”).getConstructs();
3,获取某个类的无参构造
Constructor constructor = Class.forName(“java.lang.String”).getConstructor();
4,获取某个类的有参构造
Constructor constructor = Class.forName(“java.lang.String”).getConstructor(参数类型);
5,通过Constructor对象实例化对象
String str = (String)constructor.newInstance(new StringBuffer(“abc”));
示例:
package in.cast;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ReflectTest {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
//获取Class对象
String str = new String("abc");
Class clazz1 = String.class;
Class clazz2 = str.getClass();
Class clazz3 =Class.forName("java.lang.String");
System.out.println(clazz1 == clazz2);//true
System.out.println(clazz1 == clazz3);//true
//使用Constructor类获取实例对象
Constructor constructor =
String.class.getConstructor(String.class);
String str2 = (String)constructor.newInstance("abc");
System.out.println(str2);
}
}
3.2,Field类
1,Field类代表某个类中一个成员变量。
2,Field类的方法
(1)getField(“成员变量名”);//只能获取公有和父类中公有
(2)getDeclaredField(“成员变量名”);//获取该类中任意成员变量,包括私有
(3)setAccessible(ture);//如果是私有字段,要先将该私有字段进行取消权限检查的能力。也称暴力访问。
(4)get(obj);//返回指定对象上Field表示的字段的值。
(5)set(obj,value);//将指定对象变量上此Field对象表示的字段设置为指定的新值。
示例:
// 得到Person的Class对象实例
Class clazz = Person.class;
// 获取有指定参数列表的构造器
Constructor constructor = clazz.getConstructor(String.class, int.class);
// 创建对象的实例
Object instance2 = constructor.newInstance("张三", 20);
System.out.println(instance2);
// 对于字段的操作
Field field = clazz.getField("name");
Object value = field.get(instance2); // 获取字段的值
System.out.println(field.getName() + " = " + value);
// 改变字段的值
field.set(instance2, "李四");
value = field.get(instance2); // 获取字段的值
System.out.println(field.getName() + " = " + value);
// 对于方法的操作(调用)
Method method = clazz.getMethod("getAge");
Integer age = (Integer) method.invoke(instance2);
System.out.println("getAge() = " + age);
3.3,Method类
1,Method类代表某个类中的一个成员方法。
2,Method类方法
(1)getMethods();//只获取公共和父类中的方法。
(2)getDeclaredMethods();//获取本类中包含私有。
(3)getMethod(“方法名”,参数.class(如果是空参可以写null));
(4)invoke(方法名 ,方法参数);
调用对应方法,如果方法是静态,invoke方法名可以为null。
3.4,用反射方式执行某个main方法
1,当要运行的类未知时,可以使用参数用于接受该类的类名,然后通过类名获得该类的main方法,然后传入参数运行这个main方法。这样就可以在写程序的时候,利用反射的特点,将程序的功能实现,后期传入需要运行的类名就行了。
3.5,数组的反射
1、具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。
2,代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类的对应Class。
3,基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用;非基本类型的一维数组,既可以当做Object类型使用,又可以当做Object[]类型使用。
示例:
package it.cast;
import java.lang.reflect.Array;
import java.util.Arrays;
public class ArrayReflect {
public static void main(String[] args) {
int [] a1 = new int[]{1,2,3};
int [] a2 = new int[3];
int[][] a3 = new int[2][3];
String [] a4 = new String[]{"a","b","c"};
System.out.println(a1.getClass().equals(a2.getClass()));//true
System.out.println(a1.getClass().equals(a3.getClass()));//false
System.out.println(a1.getClass().equals(a4.getClass()));//false
System.out.println(a1.getClass().getName());//[I
System.out.println(a4.getClass().getName());//[Ljava.lang.String;
System.out.println(a1.getClass().getSuperclass());//class java.lang.Object
System.out.println(a4.getClass().getSuperclass());//class java.lang.Object
Object obj1=a1;
Object obj2=a3;
Object obj3=a4;
// Object[] obj11=a1;//这样是不行的,因为a1中的元素是int类型,基本数据类型不是Object
Object[] obj13=a3;
Object[] obj14=a4;//这样可以,因为String数组中的元素属于Object
System.out.println(a1);//[I@4caaf64e
System.out.println(a4);//[Ljava.lang.String;@6c10a234
System.out.println(Arrays.asList(a1));//[I@4caaf64e
System.out.println(Arrays.asList(a4));//[a, b, c]
//Array工具类用于完成对数组的反射操作。如打印任意数值
printObject(a1);
printObject(a4);
printObject("abc");
}
//打印任意数值
private static void printObject(Object obj) {
Class clazz=obj.getClass();
//如果传入的是数组,则遍历
if(clazz.isArray()){
int len =Array.getLength(obj);//Array工具类获取数组长度方法
for(int x=0;x<len;x++){
System.out.println(Array.get(obj, x));//Array工具获取数组元素
}
}
else
System.out.println(obj);
}
}