一、目录
- 创建对象的方式
- 利用setAccessible操作属性
- 利用setAccessible操作方法
- 方式一:调用类中的public修饰的无参构造器。 相关方法:newInstance:调用类中的无参构造器,获取对应类的对象。
- 方式二:调用类中的指定构造器。 相关方法:
- getConstructor(Class…clazz):根据参数列表,获取对应的构造器对象。只获取public的构造器。
- getDecalaredConstructor(Class…clazz):根据参数列表,获取对应的构造器对象。获取所有构造器。
Constructor类相关方法:
- setAccessible:作用是开启和关闭取消访问安全检查,true为关闭,false为开启。
- newInstance(Object…obj):调用构造器
package com.javareflection;
import java.lang.reflect.Constructor;
public class Person {
public static void main(String[] args) throws Exception{
// 1. 先获取User类的Class对象
Class aClass = Class.forName("com.javareflection.User");
// 2. 通过无参构造器创建对象实例
Object o = aClass.newInstance();
System.out.println(o);
// 3. 通过public的有参构造器创建对象实例
Constructor constructor = aClass.getConstructor(String.class);
Object ton = constructor.newInstance("Ton");
System.out.println(ton);
Constructor constructor1 = aClass.getDeclaredConstructor(int.class, String.class);
constructor1.setAccessible(true);//如果不关闭访问安全检查,那么就不能给它赋值,因为它不是public类型的
Object wangwu = constructor1.newInstance(30, "wangwu");
System.out.println(wangwu);
}
}
class User{
private int age = 24;
private String name = "zhangsan";
public User() {
}
public User(String name) {
this.name = name;
}
private User(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "User{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
User{age=24, name='zhangsan'}
User{age=24, name='Ton'}
User{age=30, name='wangwu'}
三、利用setAccessible操作属性
通过反射获取到了类中的除了public类型的属性时,直接操作是不行的,需要关闭访问安全检查再对其进行操作。
package com.javareflection;
import java.lang.reflect.Field;
public class Animal {
public static void main(String[] args) throws Exception{
// 1. 获取Money类的Class对象
Class aClass = Class.forName("com.javareflection.Monkey");
Object o = aClass.newInstance();
System.out.println(o);
// 2. 获取public属性并修改其值
Field age = aClass.getField("age");
System.out.println(age.get(o));
age.set(o, 1000);
System.out.println(age.get(o));
// 3. 获取private属性并修改其值
Field name = aClass.getDeclaredField("name");
name.setAccessible(true);
System.out.println(name.get(o));
name.set(o, "UglyMonkey");
System.out.println(name.get(o));
}
}
class Monkey{
public int age = 500;
private String name = "monkeyKing";
@Override
public String toString() {
return "Money{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
500
1000
monkeyKing
UglyMonkey
四、利用setAccessible操作方法
package com.javareflection;
import java.lang.reflect.Method;
public class Boss {
public static void main(String[] args) throws Exception{
// 1. 获取MyBoss类的Class对象
Class aClass = Class.forName("com.javareflection.MyBoss");
Object o = aClass.newInstance();
// 2. 调用public方法
Method hi = aClass.getMethod("hi", String.class);
hi.invoke(o, "this is me");
// 3.调用非public方法
Method say = aClass.getDeclaredMethod("say", int.class, String.class, char.class);
say.setAccessible(true);
System.out.println(say.invoke(o, 20, "wang", 'F'));
System.out.println(say.invoke(null, 30, "Li", 'M'));
}
}
class MyBoss{
private int age = 40;
private static String name = "wangwu";
public MyBoss() {
}
private static String say(int n, String s, char c){
return n + " " + s + " " + c;
}
public void hi(String s){
System.out.println("hi " + s);
}
}
hi this is me
20 wang F
30 Li M
注: 如果方法或者属性是static的,那么传进入的对象o可以改成null,因为static是属性所有对象的。