Java反射实例化对象

Java 反射实例化对象

1、通过反射实例化对象
  1. 首先要获取目标类的class对象,可以通过以下三种方法
    /*
    * 获取class对象的三种方法`在这里插入代码片`
    * */
    //1.通过 类名.class
    Class personClass1 = Person.class;

    //2.通过实例化对象的getClass()方法
    Person p = new Person();
    Class personClass2 = p.getClass();

    //3.通过类的路径名path(path是完整的包名加类名),调用Class.forName(path)方法
    Class personClass3 = Class.forName("com.example.demo.reflection.Person");
  1. 通过目标的class对象来实例化目标对象
    /*
    * 通过class对象反射出类的实例化对象
    * */
    //1.直接调用class对象的newInstance(),调用了空构造函数实例化对象
    Person person1 = (Person) personClass3.newInstance();

    //2.调用class对象的getConstructor(),返回空构造器对象
    Constructor constructor1 = personClass3.getConstructor();
    Person person2 = (Person) constructor1.newInstance();

    //3.调用class对象的getConstructor(),返回带参构造器对象,
    //其实String.class等表示对应构造函数的参数类型,为了根据参数找到构造函数的重构方法
    Constructor constructor2 = personClass3.getConstructor(String.class, int.class, String.class);
    Person person3 = (Person) constructor2.newInstance("Frank", 15, "male");

    //4.调用class对象的getDeclaredConstructor(),返回带参构造器对象
    Constructor declaredConstructor = personClass3.getDeclaredConstructor(String.class, int.class, String.class);
    declaredConstructor.setAccessible(true);
    Person person4 = (Person) declaredConstructor.newInstance("Nancy", 25, "female");
2、getConstructors和getDeclaredConstructors的区别

getConstructors包含Person类的公有构造方法,而getDeclaredConstructors则包含Person类的所有构造方法

System.out.println(Arrays.toString(personClass3.getConstructors()));
System.out.println(Arrays.toString(personClass3.getDeclaredConstructors()));
--------------------------------------------------------------------------------------
[public com.example.demo.reflection.Person()]
[public com.example.demo.reflection.Person(), private com.example.demo.reflection.Person(java.lang.String,int,java.lang.String)]
3、getFields和getDeclaredFields的区别

getFields包含Person和其从父类继承来的所有public修饰的属性,而getDeclaredFields只包含Person类的所有的属性

System.out.println(Arrays.toString(personClass3.getFields()));
System.out.println(Arrays.toString(personClass3.getDeclaredFields()));
--------------------------------------------------------------------------------------
[public java.lang.String com.example.demo.reflection.Student.job]
[private java.lang.String com.example.demo.reflection.Person.name, private int com.example.demo.reflection.Person.age, private java.lang.String com.example.demo.reflection.Person.sex]
所以推荐使用下述方法反射实例化对象,此时可以调用Person类的非public修饰的构造方法
再通过setAccessible(true)来跳过权限检测,也可以通过setAccessible(true)来提高反射的性能
Constructor declaredConstructor = personClass3.getDeclaredConstructor(String.class, int.class, String.class);
declaredConstructor.setAccessible(true);
Person person4 = (Person) declaredConstructor.newInstance("Nancy", 25, "female");
上文中使用过的完整测试代码
public class demo01 {
    public static void main(String[] args) throws Exception {
        /*
        * 获取class对象的三种方法
        * */
        //1.通过 类名.class
        Class personClass1 = Person.class;

        //2.通过实例化对象的getClass()方法
        Person p = new Person();
        Class personClass2 = p.getClass();

        //3.通过类的路径名path(path是完整的包名加类名),调用Class.forName(path)方法
        Class personClass3 = Class.forName("com.example.demo.reflection.Person");

        /*
        * 通过class对象反射出类的实例化对象
        * */
        //1.直接调用class对象的newInstance(),调用了空构造函数实例化对象
        Person person1 = (Person) personClass3.newInstance();

        //2.调用class对象的getConstructor(),返回空构造器对象
        Constructor constructor1 = personClass3.getConstructor();
        Person person2 = (Person) constructor1.newInstance();

        //3.调用class对象的getConstructor(),返回带参构造器对象,
        //其实String.class等表示对应构造函数的参数类型,为了根据参数找到构造函数的重构方法
        //使用时应对应参数的public修饰的构造方法
        //Constructor constructor2 = personClass3.getConstructor(String.class, int.class, String.class);
        //Person person3 = (Person) constructor2.newInstance("Frank", 15, "male");

        //4.调用class对象的getDeclaredConstructor(),返回带参构造器对象
        Constructor declaredConstructor = personClass3.getDeclaredConstructor(String.class, int.class, String.class);
        declaredConstructor.setAccessible(true);
        Person person4 = (Person) declaredConstructor.newInstance("Nancy", 25, "female");

        System.out.println(Arrays.toString(personClass3.getConstructors()));
        System.out.println(Arrays.toString(personClass3.getDeclaredConstructors()));
        System.out.println(Arrays.toString(personClass3.getFields()));
        System.out.println(Arrays.toString(personClass3.getDeclaredFields()));
        System.out.println(person4);
    }
}

class Person extends Student {
    private String name;
    private int age;
    private String sex;
    public Person() {

    }
    private Person(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }
}
class Student {
    public String job;
    private String bilibili;
    public void method() {}
}
Java反射机制允许你在运行时检查和操作程序的内部结构,包括加载类、创建实例、访问私有成员等。通过反射,即使在编译时未知的情况下,也可以动态地创建和操作对象。下面是使用Java反射进行实例化对象的基本步骤: 1. **获取Class对象**:首先,你需要找到你要实例化的类的Class对象。你可以通过类名或ClassLoader获取。 ```java Class<?> clazz = Class.forName("com.example.MyClass"); ``` 2. **创建实例(如果为静态工厂方法)**:如果类没有无参构造函数,可以通过`newInstance()`方法创建,但这个方法通常用于静态工厂方法。 ```java Object instance = clazz.newInstance(); ``` 3. **使用Constructor实例化**:如果需要使用特定构造函数,可以获取Constructor对象并调用其newInstance方法。 ```java Constructor<?> constructor = clazz.getDeclaredConstructor(String paramType); // 假设有个带String参数的构造函数 instance = constructor.newInstance("exampleValue"); ``` 4. **使用Reflective Constructor**:使用`ReflectiveConstructor`更强大,可以处理所有参数类型,即使在编译时无法确定。 ```java Constructor<?>[] constructors = clazz.getConstructors(); Constructor<?> constructor = constructors; // 选择一个 instance = constructor.newInstance(); ``` 5. **创建对象实例**:调用`newInstance()`或`Constructor`的实例化方法即可得到新创建的对象。 **相关问题--:** 1. Java反射的局限性是什么? 2. 如何判断一个类是否支持反射? 3. 什么时候会使用反射,而不是直接实例化?
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值