反射:就是通过Class、Field、Method、Constructor这些类来 创建对象、给成员变量赋值、运行成员方法这种行为我们就称之为反射
Person类
public class Person {
private String id;
public String name;
public int age = 300;
public Person() {
System.out.println("我是空参构造方法");
}
private Person(String name){
System.out.println("我是私有的有参构造方法 通过构造方法传入的name是"+name);
}
public Person(String id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
System.out.println("我是public修饰的有参构造方法,通过构造方法传入的id是"+id+",name是"+name+",age是"+age);
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//无参 无返回值
public void function1(){
System.out.println("我是无参无返回值function1方法");
}
//无参 有返回值
public String function2(){
System.out.println("我是无参有返回值function2方法");
return "我有返回值哦";
}
//有参 无返回值
public void function3(String name){
System.out.println("我是有参无返回值function3,传入的name="+name);
}
//有参 有返回值
private int function4(int age){
System.out.println("我是有参有返回值function4,传入的age="+age);
return age;
}
}
1.获取Class对象常用的三种方式:
public class ReflectDemo6 {
public static void main(String[] args) throws ClassNotFoundException {
//获取Class对象的三种方式
//第一种通过对象.getclass方式获取
Person person = new Person();
Class extends Person> clazz1 = person.getClass();
System.out.println(clazz1);
//第二种通过Class类中的forName方法获取
//forName()方法中的参数是Person的全限定包名
Class> clazz2 = Class.forName("com.itnylg.day16.Person");
System.out.println(clazz2);
//第三种方式通过类的字节码文件获取
Class clazz3 = Person.class;
System.out.println(clazz3);
//这三种方式获取的Class对象是内存中同一个对象
System.out.println(clazz1==clazz3);//true
System.out.println(clazz1==clazz2);//true
System.out.println(clazz3==clazz2);//true
}
}
2.获取Constructor对象:
Constructor>[] getConstructors() 返回所有公共构造方法对象的数组
Constructor>[] getDeclaredConstructors() 返回所有构造方法对象的数组
ConstructorgetConstructor(Class>... parameterTypes) 返回单个公共构造方法对象
ConstructorgetDeclaredConstructor(Class>... parameterTypes) 返回单个构造方法对象
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ReflectDemo5 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Method1();//getConstructor()获取指定public修饰的构造方法
Method2();//getConstructors()获取Person类中的所有被public修饰的构造方法
Method3();//getDeclaredConstructor获取P erson类中的指定被private修饰的构造方法
Method4();//getDeclaredConstructors()获取Person类中的所有的构造方法
}
private static void Method4() throws ClassNotFoundException {
//getDeclaredConstructors()获取Person类中的所有的构造方法
//1.获取class对象
Class clazz1 = (Class) Class.forName("com.itnylg.day16.Person");
//获取Person类中所有的构造方法(无论是被private修饰还是被public修饰)
Constructor>[] constructors = clazz1.getDeclaredConstructors();
for (Constructor> constructor : constructors) {
System.out.println(constructor);
}
}
private static void Method3() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//getDeclaredConstructor获取Person类中的指定被private修饰的构造方法
//1.获取class对象
Class clazz1 = (Class) Class.forName("com.itnylg.day16.Person");
//getDeclaredConstructor()若不传参,则会默认获取被public修饰的无参构造方法(由于Person类中不存在被private修饰的空参构造方法)
Constructor constructor = clazz1.getDeclaredConstructor(String.class);
//由于只有一个参数的构造方法是被private修饰的,所以不可以直接通过newInstance()方法进行传值
//需要通过setAccessible()方法取消一下访问权限检查
//否则会报Exception in thread "main" java.lang.IllegalAccessException: Class com.itnylg.day16.ReflectDemo5
// can not access a member of class com.itnylg.day16.Person with modifiers "private"
constructor.setAccessible(true);
Person person1 = constructor.newInstance("张三");
System.out.println(person1);
}
private static void Method2() throws ClassNotFoundException {
//getConstructors()获取Person类中的所有被public修饰的构造方法
//1.获取class对象
Class clazz1 = (Class) Class.forName("com.itnylg.day16.Person");
Constructor>[] constructors = clazz1.getConstructors();
for (Constructor> constructor : constructors) {
System.out.println(constructor);
}
}
private static void Method1() throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
//getConstructor()获取指定public修饰的构造方法
//1.获取class对象
Class clazz1 = (Class) Class.forName("com.itnylg.day16.Person");
//2.获取无参构造对象constructor1
Constructor constructor1 = clazz1.getConstructor();
//获取有参构造的对象constructor2
Constructor constructor2 = clazz1.getConstructor(String.class, String.class, int.class);
//3.通过无参构造对象constructor1中的newInstance()方法获取Person类的对象person1
Person person1 = constructor1.newInstance();
//通过有参构造对象constructor2中的newInstance()方法获取Person类的对象person2,并通过有参构造的方式传入id,name,age的值
Person person2 = constructor2.newInstance("1", "张三", 25);
System.out.println(person1);
System.out.println(person2);
}
}
运行结果: Method1(): 我是空参构造方法 我是public修饰的有参构造方法,通过构造方法传入的id是1,name是张三,age是25 Person{id='null', name='null', age=300} Person{id='1', name='张三', age=25} Method2(): public com.itnylg.day16.Person() public com.itnylg.day16.Person(java.lang.String,java.lang.String,int)Method3(): 我是私有的有参构造方法 通过构造方法传入的name是张三 Person{id='null', name='null', age=300}Method4(): private com.itnylg.day16.Person(java.lang.String) public com.itnylg.day16.Person(java.lang.String,java.lang.String,int) public com.itnylg.day16.Person()
3.获取Field对象:
Field[] getFields() 返回所有公共成员变量对象的数组
Field[] getDeclaredFields() 返回所有成员变量对象的数组
Field getField(String name) 返回单个公共成员变量对象
Field getDeclaredField(String name) 返回单个成员变量对象
public class ReflectDemo7 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Method1();
Method2();
Method3();
Method4();
}
private static void Method4() throws ClassNotFoundException {
//获取Field对象
//通过Class.forName获取Class对象
Class> clazz4 = Class.forName("com.itnylg.day16.Person");
//getDeclaredFields()返回Person类中的所有成员变量对象的数组
Field[] fields = clazz4.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
}
private static void Method3() throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
//获取Field对象
//通过Class.forName获取Class对象
Class> clazz3 = Class.forName("com.itnylg.day16.Person");
//getDeclaredField() 返回Person类中被public或private修饰的单个成员变量对象
//我们以被private修饰的id为例进行讲解
Field id = clazz3.getDeclaredField("id");
//为id赋值,set()方法需要传入两个参数:Object obj,对应属性想要传入的值
//此处需要获取一个Person对象,上面我们已经讲过如何利用反射获取构造方法Constructor,我们可以使用Constructor中的newIntance方式获取Person对象
Constructor> constructor = clazz3.getConstructor();
//这里同样因为id属性值是被private修饰,需要取消访问权限检查
id.setAccessible(true);
Person person2 = (Person) constructor.newInstance();
id.set(person2,"001");
System.out.println(person2);
}
private static void Method2() throws ClassNotFoundException {
//获取Field对象
//通过Class.forName获取Class对象
Class> clazz2 = Class.forName("com.itnylg.day16.Person");
//getFields()方法返回Person中所有公共成员变量对象的数组
Field[] fields = clazz2.getFields();
for (Field field : fields) {
System.out.println(field);
}
}
private static void Method1() throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
//获取Field对象
//通过Class.forName获取Class对象
Class> clazz1 = Class.forName("com.itnylg.day16.Person");
//getField()获取Person类中指定被public修饰的公共成员变量
Field field1 = clazz1.getField("name");
Field field2 = clazz1.getField("age");
//set()方法需要传入两个参数:Object obj,对应属性想要传入的值
//此处需要获取一个Person对象,上面我们已经讲过如何利用反射获取构造方法Constructor,我们可以使用Constructor中的newIntance方式获取Person对象
Person person1 = (Person) clazz1.getConstructor().newInstance();
field1.set(person1,"张三");
//get()方法获取某个对象的属性值
Object o = field2.get(person1);//获取到person1对象的age值(field2获取的age变量的对象)
System.out.println(o);
//我们在Person类中重写了toString()方法,可以打印一下person1,看是否赋值成功
System.out.println(person1);
}
}
运行结果:
Method1(): 我是空参构造方法 300 Person{id='null', name='张三', age=300}Method2(): public java.lang.String com.itnylg.day16.Person.name public int com.itnylg.day16.Person.ageMethod3(): 我是空参构造方法 Person{id='001', name='null', age=300}Method4(): private java.lang.String com.itnylg.day16.Person.id public java.lang.String com.itnylg.day16.Person.name public int com.itnylg.day16.Person.age
4.获取Method对象:
Method[] getMethods() 返回所有公共成员方法对象的数组,包括继承的
Method[] getDeclaredMethods() 返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name, Class>... parameterTypes) 返回单个公共成员方法对象
Method getDeclaredMethod(String name, Class>... parameterTypes) 返回单个成员方法对象
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectDemo8 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// Method1();
// Method2();
// Method3();
// Method4();
}
private static void Method4() throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
//获取Method对象
//获取class对象
Class clazz4 = (Class) Class.forName("com.itnylg.day16.Person");
//getDeclaredMethod(String name, Class>... parameterTypes) 返回单个成员方法对象
//function4()方法有参数有返回值并且被private修饰
Method function4 = clazz4.getDeclaredMethod("function4", int.class);
//同样需要取消访问权限检查
function4.setAccessible(true);
Person person4 = clazz4.getConstructor().newInstance();
Object o = function4.invoke(person4, 23);
System.out.println(o);
}
private static void Method3() throws ClassNotFoundException {
//获取Method对象
//获取class对象
Class clazz3 = (Class) Class.forName("com.itnylg.day16.Person");
//getDeclaredMethods() 返回所有成员方法对象的数组,不包括继承的
Method[] declaredMethods = clazz3.getDeclaredMethods();
for (Method method : declaredMethods) {
System.out.println(method);
}
}
private static void Method2() throws ClassNotFoundException {
//获取Method对象
//获取class对象
Class clazz2 = (Class) Class.forName("com.itnylg.day16.Person");
//getMethods()返回所有公共成员方法对象的数组,包括继承的Object(每一个类都默认继承Object类)的公共成员方法对象
Method[] methods = clazz2.getMethods();
for (Method method : methods) {
System.out.println(method);
}
}
private static void Method1() throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
//获取Method对象
//获取class对象
Class clazz1 = (Class) Class.forName("com.itnylg.day16.Person");
//getMethod(String name, Class>... parameterTypes) 返回Person类单个公共成员方法对象
//function1()方法属于无参无返回值类型
Method function1 = clazz1.getMethod("function1");
//function2()方法属于无参有返回值类型
Method function2 = clazz1.getMethod("function2");
//function3()方法属于有参无返回值类型
Method function3 = clazz1.getMethod("function3", String.class);
//Object invoke(Object obj, Object... args) 运行方法
//参数一: 用obj对象调用该方法
//参数二: 调用方法的传递的参数(如果没有就不写)
//返回值: 方法的返回值(如果没有就不写)
Person person1 = clazz1.getConstructor().newInstance();
function1.invoke(person1);
Object o = function2.invoke(person1);
System.out.println(o);
function3.invoke(person1,"张三");
}
}
运行结果:
Method1(): 我是空参构造方法 我是无参无返回值function1方法 我是无参有返回值function2方法 我有返回值哦 我是有参无返回值function3,传入的name=张三Method2(): public java.lang.String com.itnylg.day16.Person.toString() public java.lang.String com.itnylg.day16.Person.getName() public java.lang.String com.itnylg.day16.Person.getId() public void com.itnylg.day16.Person.setName(java.lang.String) public void com.itnylg.day16.Person.function1() public java.lang.String com.itnylg.day16.Person.function2() public void com.itnylg.day16.Person.function3(java.lang.String) public void com.itnylg.day16.Person.setId(java.lang.String) public int com.itnylg.day16.Person.getAge() public void com.itnylg.day16.Person.setAge(int) public final void java.lang.Object.wait() throws java.lang.InterruptedException public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException public boolean java.lang.Object.equals(java.lang.Object) public native int java.lang.Object.hashCode() public final native java.lang.Class java.lang.Object.getClass() public final native void java.lang.Object.notify() public final native void java.lang.Object.notifyAll()Method3(): public java.lang.String com.itnylg.day16.Person.toString() public java.lang.String com.itnylg.day16.Person.getName() public java.lang.String com.itnylg.day16.Person.getId() public void com.itnylg.day16.Person.setName(java.lang.String) private int com.itnylg.day16.Person.function4(int) public void com.itnylg.day16.Person.setAge(int) public java.lang.String com.itnylg.day16.Person.function2() public void com.itnylg.day16.Person.function3(java.lang.String) public int com.itnylg.day16.Person.getAge() public void com.itnylg.day16.Person.setId(java.lang.String) public void com.itnylg.day16.Person.function1()Method4(): 我是空参构造方法 我是有参有返回值function4,传入的age=23 23



