反射
1.反射的概念
程序能够在运行时,观察、检测、修改自己运行时(Runtime)状态和行为的能力/特性.
2.java反射机制
在运行状态中,动态获取类的信息以及动态调用对象的方法的功能
正常方式 类---->对象 new对象---->类信息
反射方式 JavaAPI提供了Class类---->类信息
3.Java 反射机制的作用
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的属性和方法
在运行时调用任意一个对象的方法
生成动态代理
4.反射常用的Java类 主要在java.lang.reflect包中
java.lang.Class<T>类可获取类和类的成员信息
java.lang.reflect.Constructor<T>类可调用类的构造方法
java.lang.reflect.Field类可访问类的属性
java.lang.reflect.Method类可调用类的方法
5.Class类是Java反射机制的起源和入口
每个类都有自己向关的Class对象
提供了获取类信息的相关方法
Class类存放类的结构信息
类名
父类﹑接口
构造方法、方法、属性
注解 等
public class TestClass { public static void main(String[] args) { Class c1 = Map.class; Class c2 = List.class; Class c3 = Set.class; System.out.println(c1); System.out.println(c2); System.out.println(c3); Class C4 = Enum.class; Class C5 = Override.class; Class c6 = int.class; Class C7 = Integer.class; Class C8 = Integer.TYPE; System.out.println(C4); System.out.println(C5); System.out.println(c6); System.out.println(C7); System.out.println(C8); Class c9 = void.class; Class c10 = String[].class; Class c11 = double[][].class; System.out.println(c9); System.out.println(c10); System.out.println(c11); Class<Object> clz = Object.class; System.out.println(clz); } }
6.创建Class实例的三种方式
方式一 对象的getClass()方法
Person p = New Person();
Class cls = Person.getClass();
方式二 类的class属性
Class cls = Person.class;
方式三 Class.forName("全类名");
Class clazz = Class.forName("xxx.xxx. Person");
public class TestCtreateClass { public static void main(String[] args) throws ClassNotFoundException { //方式一 Class.forName //Class.forName("com.mysql.jdbc.Driver"); Class<?> cls = Class.forName("cn.bdqn.pojo.Person"); System.out.println(cls); System.out.println(cls.getName()); //方式二 类的class属性 Class<Person> personClass = Person.class; System.out.println(personClass); //方式三 对象的getClass()方法 Person person = new Person(); Class aClass = person.getClass(); System.out.println(aClass); //一个类只有一个对应的Class对象 封装了整个类的结构 System.out.println(cls.hashCode()); System.out.println(personClass.hashCode()); System.out.println(aClass.hashCode()); } }
7.理解Class对象
8.通过Class获得类信息
public class TestClassInfo { public static void main(String[] args) { Class cls = Person.class; String name = cls.getName(); System.out.println("类全名" + name); String pcSimpleName = cls.getSimpleName(); System.out.println("类名" + pcSimpleName); Package pcPackage = cls.getPackage(); System.out.println("类的包名" + pcPackage.getName()); Class superclass = cls.getSuperclass(); System.out.println("父类" + superclass.getName()); boolean annotation = cls.isAnnotation(); System.out.println("是否是注解" + annotation); boolean anInterface = cls.isInterface(); System.out.println("是否是接口" + anInterface); boolean anEnum = cls.isEnum(); System.out.println("是否是枚举" + anEnum); Class[] interfaces = cls.getInterfaces(); for (Class c : interfaces){ System.out.println("遍历接口名" + c.getName()); } //类修饰符 1 public 2private 3 public private 4 protected int modifiers = cls.getModifiers(); System.out.println("" + modifiers); String s = Modifier.toString(modifiers); System.out.println("" + s); System.out.println(Modifier.toString(2)); System.out.println(Modifier.toString(3)); System.out.println(Modifier.toString(4)); } }
9.通过Class 获得属性信息
public class TestField { public static void main(String[] args) throws NoSuchFieldException { //获得Class对象 Class<Person> cls = Person.class; //getField 获得指定属性名并且public属性信息 //属性修饰符 属性类型 属性名 Field age = cls.getField("age"); System.out.println("属性全部信息 = " + age); int modifiers = age.getModifiers(); String s = Modifier.toString(modifiers); System.out.println("属性修饰符 = " + s); Class<?> ageType = age.getType(); System.out.println("属性类型 = " + ageType); String name = age.getName(); System.out.println("属性名 = " + name); System.out.println("==============================="); //getFields 获得所有属性信息并且public for (Field f : cls.getFields()) { System.out.println("getFields= " + f.getName()); System.out.println("getFields= " + f.getType().getName()); System.out.println("getFields= " + Modifier.toString(f.getModifiers())); } System.out.println("==============================="); //getDeclaredField 获得指定属性信息 Field declaredField = cls.getDeclaredField("name"); System.out.println("declaredField = " + declaredField); Field ageField = cls.getDeclaredField("age"); System.out.println("ageField = " + ageField); System.out.println("==============================="); //getDeclaredFields 获取所有属性 for (Field field : cls.getDeclaredFields()) { System.out.println("getDeclaredFields遍历属性名 " + field.getName()); System.out.println("getDeclaredFields遍历属性类型 " + field.getType().getName()); System.out.println("getDeclaredFields遍历属性修饰符 " + Modifier.toString(field.getModifiers())); } } }
10.通过Class获得方法信息
public class TestMethod { public static void main(String[] args) throws NoSuchMethodException { //获取Class对象 Class cls = Person.class; //1.getMethod 获得指定方法信息并且public //方法修饰符 返回的数据类型 方法名 参数 Method age = cls.getMethod("setAge", int.class); System.out.println("方法全部信息 = " + age); int modifiers = age.getModifiers(); System.out.println("方法修饰符 = " + Modifier.toString(modifiers)); Class<?> returnType = age.getReturnType(); System.out.println("返回数据类型 = " + returnType); String name = age.getName(); System.out.println("方法名 = " + name); for (Class<?> ageParameterType : age.getParameterTypes()) { System.out.println("参数类型 = " + ageParameterType); } System.out.println("---------------------"); //2.getMethods 获得所有方法信息并且public for (Method method : cls.getMethods()) { System.out.println("method = " + method); } System.out.println("---------------------"); //3.getDeclaredMethod 获得指定方法信息 Method setAddress = cls.getDeclaredMethod("setAddress", String.class); System.out.println("方法全部信息 = " + setAddress); int modifiers2 = setAddress.getModifiers(); System.out.println("方法修饰符 = " + Modifier.toString(modifiers2)); Class<?> returnType2 = setAddress.getReturnType(); System.out.println("返回数据类型 = " + returnType2); String name2 = setAddress.getName(); System.out.println("方法名 = " + name2); for (Class<?> parameterType : setAddress.getParameterTypes()) { System.out.println("方法参数 = " + parameterType.getName()); } System.out.println("---------------------"); //4.getDeclaredMethods 获得所有方法信息 //修饰符 返回值类型 方法名 (参数列表){} for (Method m : cls.getDeclaredMethods()) { //修饰符 int mf = m.getModifiers(); String s = Modifier.toString(mf); //返回值类型 Class<?> mReturnType = m.getReturnType(); //方法名 String mName = m.getName(); //参数 Class<?>[] all = m.getParameterTypes(); String paramStr = ""; for (int i = 0; i <all.length ; i++) { paramStr +=all[i].getSimpleName() + " p"+i+","; } if (paramStr.length()>0){ paramStr = paramStr.substring(0,paramStr.length()-1); } System.out.println(s + " " +mReturnType.getName()+" "+name + "("+paramStr+"){ }"); } } }
11.通过Class获得构造方法信息
public class TestConstructor { public static void main(String[] args) throws NoSuchMethodException { //获取Class实例 Class<Person> cls = Person.class; //1.getConstructor 指定参数的构造并且public Constructor<Person> con = cls.getConstructor(int.class); System.out.println("方法全部信息 = " + con); System.out.println("======================"); //2.getConstructors 所有构造并且public Constructor<?>[] cons = cls.getConstructors(); for (Constructor<?> constructor : cons) { System.out.println("constructor = " + constructor); } System.out.println("======================"); //3.getDeclaredConstructor 获得构造 Constructor<Person> declaredConstructor = cls.getDeclaredConstructor(String.class); System.out.println("declaredConstructor = " + declaredConstructor); System.out.println("======================"); //4.getDeclaredConstructors 获得所有构造 //权限修饰符 方法名 (参数列表...){} for (Constructor<?> constructor : cls.getDeclaredConstructors()) { //修饰符 int modifiers = constructor.getModifiers(); String s = Modifier.toString(modifiers); //方法名 String name = constructor.getName(); //参数 Class<?>[] all = constructor.getParameterTypes(); String paramStr = ""; for (int i = 0; i < all.length; i++) { paramStr += all[i].getSimpleName() +" p"+i+ ","; } if (paramStr.length()>0){ paramStr = paramStr.substring(0,paramStr.length()-1); } System.out.println(s+" " + name + "(" +paramStr+ "){ }" ); } } }
12 通过Class实例创建对象两种方式
方式一 Class.newInstance()方法
Class<Person> cls = Person.class;
Person p1 = cls.newInstance();
方式二 Class.getDeclaredConstructor() 构造方法 newInstance()
Class<Person> cls2 = Person.class;
Constructor<Person> constructor = cls2.getDeclaredConstructor();
Person p2 = constructor.newInstance();
public class TestInstance { public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { //通过反射创建对象 //方式一 Class对象 newInstance() 方法 Class<Person> cls = Person.class; Person p1 = cls.newInstance(); p1.setAge(18); System.out.println("p1.getAge() = " + p1.getAge()); //方式二 Class对象 getDeclaredConstructor() 构造 newInstance() Class<Person> cls2 = Person.class; Constructor<Person> constructor = cls2.getDeclaredConstructor(); Person p2 = constructor.newInstance(); p2.setAge(18); System.out.println("p2.getAge() = " + p2.getAge()); } }
13.反射机制 操作属性对象 属性赋值
public class TestOperateField { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InstantiationException { //获得Class对象 Class<Person> cls = Person.class; //获得Field属性对象 Field address = cls.getDeclaredField("address"); //反射创建对象 Person person = cls.newInstance(); //设置禁止检查 address.setAccessible(true); //反射思想---------->属性对象赋值 address.set(person,"加勒比海岸"); Object o = address.get(person); System.out.println(o); } }
14.反射机制 操作方法对象 传参
public class TestOperateMethod { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { //获得Class对象 Class<Person> cls = Person.class; //获得Method对象 Method setName = cls.getDeclaredMethod("setName", String.class); //反射创建对象 Person person = cls.newInstance(); //禁止检查 setName.setAccessible(true); //反射思想---------->方法对象 setName.invoke(person,"张三"); System.out.println("person.getName() = " + person.getName()); } }
15.案例
public class Computer { public void run(){ System.out.println("Running..."); } public void close(){ System.out.println("Closed!"); } //升级后的2代计算机:USB功能 public void useUSB(USB usb){ if(usb != null){//如果设备连接上,则开始使用设备功能 usb.connection(); usb.close(); } } }
public interface USB { public void connection();//设备连接 public void close();//设备断开 }
public class Keyboard implements USB { @Override public void connection() { System.out.println("键盘正在使用..."); } @Override public void close() { System.out.println("键盘已断开连接!"); } }
public class Mouse implements USB { @Override public void connection() { System.out.println("鼠标正在使用..."); } @Override public void close() { System.out.println("鼠标已断开连接!"); } }
public class Test { public static void main(String[] args) throws Exception { Computer mc = new Computer(); //我们只需要知道封装设备的类名即可 String className = "cn.bdqn.demo.Keyboard"; Class<?> c = Class.forName(className); Object obj = c.newInstance(); USB usb = (USB)obj; mc.useUSB(usb); } }
public class Test2 { public static void main(String[] args) throws Exception { Computer mc = new Computer(); //利用IO流,使用配置文件传入类名: File config = new File("E:/T123code/TestClass/src/cn/bdqn/demo/usb.config"); FileInputStream fis = new FileInputStream(config); Properties prop = new Properties(); prop.load(fis); String className = null; className = prop.getProperty("usb"); Class<?> c = Class.forName(className); Object obj = c.newInstance(); USB usb = (USB)obj; mc.useUSB(usb); } }
usb=cn.bdqn.demo.Mouse