创建一个Person类
package com.reflect.demo;
import java.util.Arrays;
public class Person {
private String name;
private Integer age;
public String desc;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Person(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
System.out.println("Person的无参构造被调用了");
}
private Person(String name) {
super();
this.name = name;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", desc=" + desc + "]";
}
//私有方法
private void printlnOut(String name) {
System.out.println("这是私有方法" + name);
}
//main方法
public static void main(String[] args) {
System.out.println(Arrays.toString(args));
}
}
反射创建对象:
package com.reflect.demo;
import java.lang.reflect.Constructor;
import org.junit.Test;
public class ReflectDemo {
// 通过反射创建对象(无参构造)
@Test
public void demo01() throws Exception {
// 1 获得Class
Class<?> clazz = Class.forName("com.reflect.demo.Person");
// 2 获得构造对象 , 相当于:Person(),getConstructor() 获得指定形参列表的构造方法
Constructor<?> constructor = clazz.getConstructor();
// 3 获得实例 , 相当于:new Person(),newInstance() 创建实例对象,需要设置实际参数
Object newInstance = constructor.newInstance(); // 输出:Person的无参构造被调用了
}
// 上面demo01方法简写
@Test
public void demo02() throws Exception {
Class<?> clazz = Class.forName("com.reflect.demo.Person");
Object newInstance = clazz.newInstance(); // 输出:Person的无参构造被调用了
}
// 通过反射创建对象(有参构造)public
@Test
public void demo03() throws Exception {
// 1 获得Class对象
Class<?> clazz = Class.forName("com.reflect.demo.Person");
// 2clazz.getConstructor(...) 获得指定对象的指定的public构造方法
Constructor<?> constructor = clazz.getConstructor(String.class, Integer.class);
// 3 创建实例,并设置实际参数
Object newInstance = constructor.newInstance("小明", 15);
System.out.println(newInstance); // 输出: Person [name=小明, age=15, desc=null]
}
// 通过反射创建对象(有参构造)private
@Test
public void demo04() throws Exception {
// 1获得class
Class<?> clazz = Class.forName("com.reflect.demo.Person");
// 2clazz.getDeclaredConstructor(...)获得指定对象的任意构造方法
Constructor<?> constructor = clazz.getDeclaredConstructor(String.class);
// 3 通知jvm,运行实例化私有构造(默认不允许)
constructor.setAccessible(true);
// 4 获得实例对象,必须设置实际参数
Object newInstance = constructor.newInstance("小明");
System.out.println(newInstance); // Person [name=小明, age=15, desc=null]
}
}
反射操作public的普通方法:
package com.reflect.demo;
import java.lang.reflect.Method;
import org.junit.Test;
public class ReflectDemo02 {
// 反射普通public方法,设置值
@Test
public void a1() throws Exception {
Class<?> clazz = Class.forName("com.reflect.demo.Person");
Object obj = clazz.newInstance();
Method method = clazz.getMethod("setName", String.class);
method.invoke(obj, "小明");
System.out.println(obj);
}
// 反射普通public方法,取值
@Test
public void a2() throws Exception {
Class<?> clazz = Class.forName("com.reflect.demo.Person");
Object obj = clazz.newInstance();
Method method = clazz.getMethod("setName", String.class);
method.invoke(obj, "小明");
Method method2 = clazz.getMethod("getName");
String str = (String) method2.invoke(obj);
System.out.println(obj);
}
}
反射操作private的普通方法:
package com.reflect.demo;
import java.lang.reflect.Method;
import org.junit.Test;
public class ReflectDemo03 {
// 执行Person的私有方法
@Test
public void a1() throws Exception {
Class<?> clazz = Class.forName("com.reflect.demo.Person");
Object obj = clazz.newInstance();
Method declaredMethod = clazz.getDeclaredMethod("printlnOut", String.class);
declaredMethod.setAccessible(true);
Object invoke = declaredMethod.invoke(obj, "小明星");
System.out.println(invoke); // 输出null因为printlnOut没有返回值
}
}
反射操作main方法:
package com.reflect.demo;
import java.lang.reflect.Method;
import org.junit.Test;
public class ReflectDemo04 {
@Test
public void a1() throws Exception {
// 1 获得Class对象
Class<?> clazz = Class.forName("com.reflect.demo.Person");
// 2获得main方法
Method method = clazz.getMethod("main", String[].class);
String[] args = {"123", "abc", "xxx"};
// 参数1:为实例对象(变量名),static方法不需要
// 参数2:main方法执行的实际参数
// 可变参数在执行时,JVM内部将传递实参数组打散,变成多个参数。等效于method.invoke(null, "abc","123","xxx")
// method.invoke(null, args); //错误写法
// 数组参数需要特殊处理
// 方式1:将 String[]转换成Object,可变参数将不处理数组
method.invoke(null, (Object)args);
// 方法2:将提供二维数组,args将作为二维数组的第一个数。
method.invoke(null, new Object[] {args});
}
}
反射操作public和private字段:
package com.reflect.demo;
import java.lang.reflect.Field;
import org.junit.Test;
public class ReflectDemo05 {
//反射对public的字段操作
@Test
public void a1() throws Exception {
// 1 获得实例对象
Class<?> clazz = Class.forName("com.reflect.demo.Person");
Object obj = clazz.newInstance();
// 2 给字段赋值
Field field = clazz.getField("desc");
field.set(obj, "描述");
System.out.println(obj); // 输出Person [name=null, age=null, desc=描述]
// 3 获得字段值
String str = (String) field.get("desc");
System.out.println(str);
}
@Test
public void a2() throws Exception{
//1 获得实例
Class clazz = Class.forName("com.reflect.demo.Person");
Object obj = clazz.newInstance();
// 2 获得声明的字段(私有)
Field declaredField = clazz.getDeclaredField("desc");
// 3 设置运行访问私有(暴力)
declaredField.setAccessible(true);
// 4 设置数据
declaredField.set(obj, "描述");
System.out.println(obj); // 输出Person [name=null, age=null, desc=描述]
// 5 获得数据
String str = (String) declaredField.get("desc");
System.out.println(str);
}
}