Java 反射获取类实例的4种方式、创建对象、调用构造器、属性或方法
  DosddciaWHNX 2023年12月06日 18 0


1、在编译的时候不确定用哪个属性或方法时,则可以使用反射。

2、getDeclared系列方法:

  • 可以获取当前运行时类及其父类中声明为 public 访问权限的属性或方法
  • 获取当前运行时类中声明为 public 的构造器(不包含父类)

3、非Declared系列方法:

  • 可以获取当前运行时类中声明的所有属性、方法或构造器(不包含父类);当遇到私有结构时,先执行 setAccessible(true) 方法就可以访问了,否则会报错。
public class Person {
    private String name;
    public int age;
    public String nation;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person(String name, int age, String nation) {
        this.name = name;
        this.age = age;
        this.nation = nation;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getNation() {
        return nation;
    }

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

    public void setAge(int age) {
        this.age = age;
    }

    public void setNation(String nation) {
        this.nation = nation;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", nation='" + nation + '\'' +
                '}';
    }
    public void show() {
        System.out.println(this);
    }
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectTest {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, NoSuchFieldException {
//        Person p1 = new Person("Tom", 12, "中国");

        //通过反射,创建运行时类对象
        Class clazz = Person.class;// or Class<Person> clazz = Person.class;
        Constructor cons = clazz.getConstructor(String.class, int.class);
        Person p1 = (Person) cons.newInstance("Tom", 14);
        System.out.println(p1);
        //getConstructors(): 获取当前运行时类中声明为public的构造器(不包含父类构造器)
        Constructor[] constructors = clazz.getConstructors();
        for (Constructor c: constructors) {
            System.out.println(c);
        }
        //getDeclaredConstructors(): 获取当前运行时类中声明的所有构造器
        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
        for (Constructor c: declaredConstructors) {
            System.out.println(c);
        }


        //getFields(): 获取当前运行时类及其父类中声明为public访问权限的属性
        Field[] fields = clazz.getFields();
        for (Field f: fields) {
            System.out.println(f);
        }
        //getDeclaredFields(): 获取当前运行时类中声明的所有属性(不包含父类)
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field f: declaredFields) {
            System.out.println(f);
        }
        //getDeclaredField(属性名称): 通过反射,调用对象指定的属性
        Field age = clazz.getDeclaredField("age");
        if(!age.isAccessible()) {
            age.setAccessible(true);//设置为可访问,否则私有属性不可访问
        }
        age.set(p1, 10);
        System.out.println(p1);


        //getMethods(): 获取当前运行时类及其父类中声明为public访问权限的方法
        Method[] methods = clazz.getMethods();
        for (Method method: methods) {
            System.out.println(method);
        }
        //getDeclaredMethods(): 获取当前运行时类中声明的所有方法(不包含父类)
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method method: declaredMethods) {
            System.out.println(method);
        }
        //getDeclaredMethod(方法名称): 通过反射,调用对象指定的方法
        Method show = clazz.getDeclaredMethod("show");
        if(!show.isAccessible()){
            show.setAccessible(true);//设置为可访问,否则私有方法不可访问
        }
        show.invoke(p1);


        //获取类实例的4种方式
        //方式一:.class(有限制:编译时就把要调用的类名确定了)
        Class clazz1 = Person.class;
        System.out.println(clazz1);//class reflectTest.Person
        //方式二:通过运行时类对象(有限制:提前是本身就有该类的对象)
        Person p = new Person("Tom", 12);
        Class clazz2 = p.getClass();
        System.out.println(clazz2);//class reflectTest.Person
        //方式三:调用class的静态方法(常用)
        Class clazz3 = Class.forName("reflectTest.Person");
        System.out.println(clazz3);//class reflectTest.Person
        //方式四:使用类的加载器:ClassLoader(不常用)
        ClassLoader classLoader = ReflectTest.class.getClassLoader();
        Class clazz4 = classLoader.loadClass("reflectTest.Person");
        System.out.println(clazz4);//class reflectTest.Person
    }
}
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月06日 0

暂无评论

推荐阅读
  2Vtxr3XfwhHq   2024年05月17日   53   0   0 Java
  Tnh5bgG19sRf   2024年05月20日   107   0   0 Java
  8s1LUHPryisj   2024年05月17日   46   0   0 Java
  aRSRdgycpgWt   2024年05月17日   47   0   0 Java
DosddciaWHNX