1 反射
1.1 反射概述
- java反射机制是在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
- 换句话说,反射就是通过Class对象,去操作对应字节码文件中的成员变量、构造方法和成员方法。
- 要想剖析一个类,必须先要获取到该类的字节码文件对象。而剖析使用的就是Class类中的方法。所以先要获取到每一个字节码文件对应的Class类型的对象。
1.2 获取Class对象的三种方式
- ①通过对象.getClass()方法获取Class对象。
package com.xuweiwei; public class Person { private String name; private Integer age; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
package com.xuweiwei; public class ClassDemo { public static void main(String[] args) { Person p = new Person(); Class<? extends Person> c = p.getClass(); System.out.println(c); } }
- ②通过类名.class获取对应的Class对象。
package com.xuweiwei; public class ClassDemo { public static void main(String[] args) { Class<Person> c = Person.class; System.out.println(c); } }
- ③通过Class.forName("完整类名")获取Class对象。
package com.xuweiwei; public class ClassDemo { public static void main(String[] args) throws ClassNotFoundException { Class<?> c = Class.forName("com.xuweiwei.Person"); System.out.println(c); } }
1.3 反射获取构造方法
- 方法:获取指定参数的公共的构造方法(构造方法的修饰符是public)
public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException,SecurityException
- 方法:获取所有公共的构造方法
public Constructor<?>[] getConstructors() throws SecurityException
- 方法:获取指定参数的构造方法(构造方法的修饰符可以是public也可以是private或其它)
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) throws NoSuchMethodException,SecurityException
- 方法:获取所有的构造方法
public Constructor<?>[] getDeclaredConstructors() throws SecurityException
- 示例:通过反射获取无参构造方法并使用
package com.xuweiwei; public class Person { private String name; private Integer age; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
package com.xuweiwei; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class ClassDemo { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Class<?> c = Class.forName("com.xuweiwei.Person"); Constructor<?> constructor = c.getConstructor(); System.out.println(constructor);//public com.xuweiwei.Person() Object o = constructor.newInstance();//创建对象 System.out.println(o); } }
- 示例:通过反射获取有参构造方法并使用
package com.xuweiwei; public class Person { private String name; private Integer age; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
package com.xuweiwei; import java.lang.reflect.Constructor; public class ClassDemo2 { public static void main(String[] args) throws Exception { Class<?> c = Class.forName("com.xuweiwei.Person"); Constructor<?> constructor = c.getConstructor(String.class, Integer.class); Object o = constructor.newInstance("许威威", 20); System.out.println(o);//Person{name='许威威', age=20} } }
- 示例:反射获取私有构造方法并使用
package com.xuweiwei; public class Person { private String name; private Integer age; private Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
package com.xuweiwei; import java.lang.reflect.Constructor; public class ClassDemo3 { public static void main(String[] args) throws Exception { Class<?> c = Class.forName("com.xuweiwei.Person"); Constructor<?> constructor = c.getDeclaredConstructor(); //需要 constructor.setAccessible(true); Object o = constructor.newInstance();//Person{name='null', age=null} System.out.println(o); } }
1.4 反射获取属性
- 上面的概念并不准确,在java中属性的定义不是上述的,准备的讲,应该获取Filed。
- 方法:获取指定名称的Filed对象
public Field getDeclaredField(String name) throws NoSuchFieldException,SecurityException
- 方法:获取所有的Field对象数组
public Field[] getDeclaredFields() throws SecurityException
- 方法:获取指定名称的公共的Field对象
public Field getField(String name) throws NoSuchFieldException,SecurityException
- 方法:获取所有的公共的Field对象
public Field[] getFields()throws SecurityException
- 示例:获取指定的私有属性,并赋值
package com.xuweiwei; public class Person { private String name; private Integer age; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
package com.xuweiwei; import java.lang.reflect.Field; public class ClassDemo4 { public static void main(String[] args) throws Exception{ Class<?> c = Class.forName("com.xuweiwei.Person"); Object o = c.newInstance(); Field nameField = c.getDeclaredField("name"); nameField.setAccessible(true); nameField.set(o,"许威威"); System.out.println(o); } }
1.5 反射获取方法
- 方法:获取所有公共的方法
public Method[] getMethods() throws SecurityException
- 方法:获取指定参数和名字的公共的方法
public Method getMethod(String name,Class<?>... parameterTypes)throws NoSuchMethodException,SecurityException
- 方法:获取所有的方法
public Method[] getDeclaredMethods() throws SecurityException
- 方法:获取指定参数和名字的方法
public Method getDeclaredMethod(String name,Class<?>... parameterTypes)throws NoSuchMethodException,SecurityException
- 示例:反射获取有参无返回值的成员方法并调用
package com.xuweiwei; public class Person { private String name; private Integer age; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
package com.xuweiwei; import java.lang.reflect.Method; public class ClassDemo4 { public static void main(String[] args) throws Exception{ Class<?> c = Class.forName("com.xuweiwei.Person"); Object o = c.newInstance(); Method setName = c.getDeclaredMethod("setName", String.class); setName.setAccessible(true); setName.invoke(o,"许威威"); System.out.println(o); } }
2 动态代理
3 枚举
4 注解