反射的描述:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,1、必须先要获取到该类的字节码文件对象。而解剖2、使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
红色1:有三种方式可以得到字节码文件对象
a:
//类加载的方式,也是类获取类对象的方式(是类对象,而不是类的对象)
//1、通过对象的getClass方法获得
User user = new User();
//拿到类
Class cls1 = user.getClass();
// Class cls2 = User.class;
// try {
// Class cls3 = Class.forName("User");
//
// } catch (ClassNotFoundException e) {
// e.printStackTrace();
// }
System.out.println(cls1.getSuperclass());
System.out.println(cls1.getName());
System.out.println(cls1.getSimpleName());
注意:这个方法必须先new出对象
b:
直接在类后面加点class
C:
通过Class类的方法进行加载,得到User实体类的字节码文件cls;
Class cls = Class.forName("Reflect.User");
三种方式常用第三种,因为第一种对象都有了还要反射干什么。第二种需要导入类的包,依赖太强,不导包就抛编译错误。一般都第三种,一个字符串可以传入也可写在配置文件中等多种方法。
反射的解释:
一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。
属性对象调用赋值:
package Reflect;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class FieldDemo {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
Class cls1 = Class.forName("Reflect.User");
User user1 = (User)cls1.newInstance();
//获取属性
Field[] fields = cls1.getDeclaredFields();
//遍历属性
for (Field field:fields) {
System.out.println("类User的属性名为:"+field.getName()+"," +
"对应的修饰权限为:"+ Modifier.toString(field.getModifiers()));
}
//得到属性的名称后进行属性操作
Field fName = cls1.getDeclaredField("name");
fName.set(user1,"伍棋烽");
System.out.println(fName.get(user1));
Field fId = cls1.getDeclaredField("id");
fId.setAccessible(true);
fId.set(user1,1001);
System.out.println(fId.get(user1));
}
}
类方法对象调取使用:
package Reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class MethodDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
Class cls = Class.forName("Reflect.User");
User user = (User)cls.newInstance();
//返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,
// 包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
Method[] methods = cls.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
System.out.println(Modifier.toString(methods[i].getModifiers()) + " "
+methods[i].getReturnType()+" "+methods[i].getName());
}
//方法的调用(只调用了一个形式参数的方法)单个参数
//String.class是形式参数,但是要转成对应的class对象形式
Method method1 = cls.getDeclaredMethod("f2",String.class);
//直接打印
method1.invoke(user,"102030");
//多个参数时候要用 new class[]装起来
Method method2 = cls.getDeclaredMethod("f2",new Class[]{String.class,int.class});
method2.invoke(user,"伍棋烽",123);
//带返回值
Method method3 = cls.getDeclaredMethod("f1",null);
Object o = method3.invoke(user,null);
System.out.println("方法f1的返回值是:"+o);
//带参数、带返回值的方法
Method method4 = cls.getDeclaredMethod("f5",int.class);
Object o2 = method4.invoke(user,250);
System.out.println("f5的返回值是:"+o2);
}
}