反射
- java反射机制是在运行状态中,对于任何一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的方法的功能成为java语言的反射机制。
- 作用:动态获取类的信息,进一步实现需要的功能
反射相关API
- Class 类型
- Constructor 构造方法
- Method 方法
- Field 属性
- 除了Class外,其他类都位于java.lang.reflect包中
- 反射API将类的类型、方法、属性都封装成了类
Class类
- Class类的对象表示正在运行的Java应用程序中的类和接口.
- 获得Class类的三种方法
/*
反射机制获得类的信息,并创建对象
要使用Class类的方法,必须先获得Class类的实例,获得Class类 实例的常用方法有如下三个
*/
Class c1 = Car.class;//类名.class方式
System.out.println(c1);//class com.ffyc.dormMS.reflect.Car
Class c2 = new Car().getClass();//Object类中的getClass方法
System.out.println(c2);
System.out.println(c1==c2);//true
String carpath = "com.ffyc.dormMS.reflect.Car";
Class c3 = Class.forName(carpath);//Class类的静态方法
System.out.println(c3);
System.out.println(c2==c3);//true
Car car = (Car)c1.newInstance();//创建由此 类对象表示的类的新实例。
Constructor类
- Constructor类可以通过getXXX方法获得构造方法的基本信息
- Constructor实例通过Class实例获得(newInstance())
String carpath = "com.ffyc.dormMS.reflect.Car";
Class c3 = Class.forName(carpath);//根据类的地址将类信息加载到内存中,并创建类的Class对象
/*
//getConstructor(参数类型) 获得指定的公共的构造方法
Constructor con =c3.getConstructor();//无参
Car car = (Car)con.newInstance();//通过Constructor类中newInstance()创建对应类的对象
*/
/*
//有参
Constructor con = c3.getConstructor(String.class, String.class);
Car car = (Car) con.newInstance("宝马","黑色");
*/
/*
//获得私有的构造方法
Constructor con1 = c3.getDeclaredConstructor(String.class,String.class);
con1.setAccessible(true);
Car car = (Car) con1.newInstance("宝马","黑色");
System.out.println(car);
*/
/*
获得所有的构造方法(包括私有的)
Constructor con = c3.getDeclaredConstructor(String.class, String.class);
Car car = (Car) con.newInstance("宝马","黑色");
System.out.println(car);
*/
//Constructor类可以通过getXXX方法获得构造方法的基本信息
Constructor[] cons = c3.getDeclaredConstructors();//返回一个反映 Constructor对象表示的类声明的所有 Constructor对象的数组类
for (Constructor con : cons){
System.out.println(con.getName());
System.out.println(con.getParameterCount());
System.out.println(con.getParameterTypes());
}
Field类
- Field类将类的属性进行封装,可以获得属性的基本信息、属性的值,也可以对属性进行赋值
- 获得Field实例,都是通过Class中的方法实现
/*
反射机制获得类的信息,并创建对象
要使用Class类的方法,必须先获得Class类的实例,获得Class类 实例的常用方法有如下三个
*/
String carpath = "com.ffyc.dormMS.reflect.Car";
Class c3 = Class.forName(carpath);//Class类的静态方法
Car car = (Car)c3.newInstance();
/*
返回一个 Field对象,它反映此表示的类或接口的指定属性的类对象。
Field namef = c3.getField("name" );
namef.set(car,"宝马");//设定值
System.out.println(namef.get(car));//获取值
*/
//返回一个 Field对象,它反映此表示的类或接口的所有属性的类对象
Field[] fs = c3.getDeclaredFields();
for (Field f : fs){
f.setAccessible(true);
if(f.getName().equals("name")){
f.set(car,"宝马");
}
if(f.getName().equals("color")){
f.set(car,"黑色");
}
}
Method类
- Method类将类中的方法进行封装,可以动态获得方法的信息
- getName:获得方法名字
- getParameterTypes:获得方法参数类型,把参数封装到一个对象中去除了动态获得方法信息外,
- Method还能动态调用某一个对象的具体方法invoke(Object obj, Object… args) :使用obj调用该方法,参数为args
- Method实例都是通过Class类的方法获得
- Method getMethod(String name, Class… parameterTypes) :通过指定方法名,参数类型,返回一个 Method实例
String carpath = "com.ffyc.dormMS.reflect.Car";
Class c = Class.forName(carpath);//Class类的静态方法
Car car = (Car)c.newInstance();
/*Method m = c.getMethod("run");//访问无参公共方法 参数是方法名
m.invoke(car);//调用该方法
Method m1 = c.getMethod("run",int.class);//访问有参公共方法
m1.invoke(car,5);
Method m2 = c.getDeclaredMethod("stay");
m2.setAccessible(true);//访问私有方法要设置获取访问权限
m2.invoke(car);*/
Field[] fs = c.getFields();
for (Field f : fs){
Method m4 = c.getMethod("get"+f.getName().substring(0,1).toUpperCase()+f.getName().substring(1));
System.out.println(m4.getName());
System.out.println(m4.getTypeParameters());
m4.invoke(car);
}