您的位置:首页 > 其它

通过反射获取类对象的属性和方法及破坏私有属性

2019-04-27 14:46 190 查看
版权声明:本文为小匠心原创文章,转载请注明出处。 https://blog.csdn.net/qq_36957885/article/details/89601568

1.Class类中要掌握的方法

[code]import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test02 {
public static void main(String[] args) throws Exception {
Class<?> person = Class.forName("Person");
// 获得类对象的一个属性
Field name = person.getDeclaredField("name");
System.out.println(name);
// 获得一个具体的方法
Method getName = person.getDeclaredMethod("getName", new Class[]{});
System.out.println(getName);
Method setName = person.getDeclaredMethod("setName", new Class[]{String.class});
System.out.println(setName);
//获得构造器
Constructor<?> constructor = person.getDeclaredConstructor(new Class[]{});

// 获得带参数的构造器(参数得必须跟类对象的构造方法参数一致)
Constructor<?> constructor1 = person.getDeclaredConstructor(Integer.class, String.class, String.class);
System.out.println(constructor1);
}
}

2.通过反射的方式赋值

 

[code]import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test03 {
public static void main(String[] args) throws Exception {
Class<?> person = Class.forName("Person");
//获得构造器
Constructor<?> constructor = person.getDeclaredConstructor(new Class[]{});
// 根据类的默认构造器来获得一个对象
Object o = constructor.newInstance(new Object[]{});
System.out.println(o);

// 根据类的有参构造器来获得一个对象
//        Constructor<?> constructor1 = person.getDeclaredConstructor(Integer.class, String.class, String.class);
//        Object o1 = constructor1.newInstance(1, "李四", "男");
//        System.out.println(o1);
// 获得类的所有方法
Method[] methods = person.getDeclaredMethods();
for (Method m : methods) {
// 获得方法的名字
String name = m.getName();
// 获得是否以set开始
boolean startsWith = name.startsWith("set");
if(startsWith) {
// 获得到了set字符串后面的值
String fieldName = name.substring(3);
/*
* 获得属性的名字
* 因为我们的get set方法对应的属性名称第一位是大写,所以通过substring进行截取并转换成小写,最后拼上后面的半截属性的名称
* 则拼接出我们类对象的属性名称
* 然后通过getDeclaredField方法来获得所对应的属性也就是   private 类型  属性名称
* */
fieldName = fieldName.substring(0, 1).toLowerCase()+fieldName.substring(1);
// 获得方法所对应的属性
Field field = person.getDeclaredField(fieldName);

/*
* 获得属性的具体类型,获得属性对应的类型
* 知道属性之后还得知道它具体类型
* */
Class<?> type = field.getType();
if(type == Integer.class) {
// 反射调用set方法并赋值
m.invoke(o, 5);
}

if(type == String.class && "name".equals(fieldName)) {
m.invoke(o, "李四");
}

if(type == String.class && "gender".equals(fieldName)) {
m.invoke(o, "男");
}

}
}
System.out.println(o);
}
}

3.通过反射调用get方法及调用静态方法

[code]import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test04 {
public static void main(String[] args) throws Exception {
Class<?> person = Class.forName("Person");
// 获得构造器
Constructor<?> constructor = person.getDeclaredConstructor(new Class[]{});
// 根据类的默认构造器来获得一个对象
Object o = constructor.newInstance(new Object[]{});
// 获得name的set方法
Method setName = person.getDeclaredMethod("setName", String.class);
// 使用反射给name设置值
Object invoke = setName.invoke(o, new Object[]{"张三"});

// 获得name的get方法
// Method getName = person.getDeclaredMethod("getName", new Class[]{});

// 这样也行,但是不建议这样使用
// Method getName = person.getDeclaredMethod("getName", null);

// 也可这样使用
Method getName = person.getDeclaredMethod("getName");

// 使用反射调用getName获得类对象属性的值
Object invoke1 = getName.invoke(o, new Object[]{});
System.out.println(invoke1);

// 反射调用静态方法
Method printInfo = person.getDeclaredMethod("printInfo");
// 因为该方法并没有返回值,所以直接可这样调用
printInfo.invoke(null, null);
printInfo.invoke(null);

}
}

4.通过反射调用私有属性设置权限

[code]import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test05 {
public static void main(String[] args) throws Exception {
Class<?> person = Class.forName("Person");
// 获得构造器
Constructor<?> constructor = person.getDeclaredConstructor(new Class[]{});
Object o = constructor.newInstance(new Object[]{});
// 根据方法名字获得属性对象
Field name = person.getDeclaredField("name");
/*
* 这样直接设置值,会报错,因为我们的类对象的属性修饰符是私有的
* 所以这就涉及到了设置权限的问题
* setAccessible破坏掉私有属性
* 静态方法也可设置权限
* */
name.setAccessible(true);
name.set(o, "张三");

// 获得属性的类型
Class<?> type = name.getType();
System.out.println(type);

}
}

类对象如下:

[code]public class Person {
private Integer id;
private String name;
private String gender;

public Person() {
}

public Person(Integer id, String name, String gender) {
this.id = id;
this.name = name;
this.gender = gender;
}

public static void printInfo(){
System.out.println("我是静态方法,反射把我给调用咯");
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getGender() {
return gender;
}

public void setGender(String gender) {
this.gender = gender;
}

@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
'}';
}
}

 

 

 

主要过程看注释,交流可评论在下方!

 

 

 

 

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐