Java基础之反射

通过反射实现一个类实例化对象

假设我们有一个 Person类
属性 : private level、public name、public age
方法 : private show(String msg) 、public show2()
构造器: 各种public的以及一个 private 带一个 String name参数的

得到这个类

Class clazz = Person.class;

使用公共的构造器、属性、方法

newInstance(): 调用此方法可以创建对应的运行时类的对象
公共构造器

// 通过反射,创建Person类的对象
        Constructor cons = clazz.getConstructor(int.class, String.class); // 得到这个构造器
        Object obj = cons.newInstance(70, "70");  // 构造器的参数赋值
        Person p = (Person)obj;  // 得到了一个实例对象
        System.out.println(p.toString());

公共属性

// 通过反射,调用对象指定的属性
        Field age = clazz.getDeclaredField("name");  // 得到这个类的属性
        age.set(p, "hahahah");   // 指明那个实例对象以及修改的值
        System.out.println(p.name);  // 输出查看
        System.out.println(p.toString());

公共的方法

// 调用方法
        Method show = clazz.getDeclaredMethod("show2"); // 得到这个类的方法
        show.invoke(p);  // 实例话对象调用

使用私有的构造器、属性、方法

私有的构造器、属性、方法比公共的多一个步骤就是 xxx.setAccessible(true);
私有的构造器

// 调用私有的构造器
        Constructor cons1 = clazz.getDeclaredConstructor(String.class); // 得到这个类的私有构造器
        cons1.setAccessible(true);   // 应该是设置可以进行使用(私有的设置)
        Person p1 = (Person) cons1.newInstance("小小怪");  // 构造传值
        System.out.println(p1);

私有的属性

		Field level = clazz.getDeclaredField("level");   // 得到这个类的私有属性
        level.setAccessible(true);  // 调用私有属性必须要设置
        level.set(p1, 7854);    // 为这个私有属性赋值
        System.out.println(p1);

私有的方法

		Method method1 = clazz.getDeclaredMethod("show", String.class); // 得到这个类的私有方法
        method1.setAccessible(true);  
        method1.invoke(p1, "小小怪下士");

获取 class的实例的方式

具体代码如下

@Test
    public void  getclassTest() throws ClassNotFoundException {
        // 方式1  通过运行时,类的属性 .class
        Class clazz = Person.class;
        System.out.println(clazz);

        // 方式2  通过运行时,类的对象调用 getClass()
        Person p = new Person();
        System.out.println(p.getClass());

        // 方式3  通过Class的静态方法  forName(String classPath)
        Class clazz1 = Class.forName("jzq.com.demo01.Person");
        System.out.println(clazz);

        // 方式4  通过类的加载器(就是运行的类)  ClassLoader
        ClassLoader classLoader = getclassTest.class.getClassLoader();
        Class clazz2 = classLoader.loadClass("jzq.com.demo01.Person");
        System.out.println(clazz2);

        //  判断是否一样

        System.out.println(clazz == clazz1);   // true
        System.out.println(clazz1 == clazz2);   // true
        System.out.println(clazz2 == p.getClass());   // true

    }

动态生产类的实例

package jzq.com.demo01;

import org.junit.Test;

import java.util.Random;

public class dtx {
    @Test
    public void Test01() {
        for (int i = 0; i < 100; i++) {
            int num = new Random().nextInt(2);
            String classPath = "";
            switch (num) {
                case 0:
                    classPath = "jzq.com.demo01.Person1";

                    break;
                case 1:
                    classPath = "jzq.com.demo01.Anim";
                    break;
            }

            try {
                Object obj = getInstance1(classPath);
                System.out.println(obj);
            }catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    public static Object getInstance1(String classPath) throws Exception {
        Class clazz = Class.forName(classPath); // 动态获取类
        return clazz.newInstance();
    }

    public Object getInstance2(Class classT) throws Exception {
        Class clazz = classT; // 动态获取类
        return clazz.newInstance();
    }
}

class Person1 {
    String name;

    public  Person1() {}

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

    @Override
    public String toString() {
        return "Person1{" +
                "name='" + name + '\'' +
                '}';
    }
}

class Anim {
    int age;

    public  Anim() {}

    public Anim(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Anim{" +
                "age=" + age +
                '}';
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值