创建运行时类的对象

不是通过new 构造器的方式,而是用反射的方式创建
通过反射创建对应的运行时类的对象:对应的是哪个运行时类,只能创建这个类的对象
newInstance(),调用此方法创建运行时类的对象
这个方法中实际上还是调用的是类的构造器
Object obj = clazz.newInstance();内部调用了Person类(运行时类)的空参构造器
证明方法很简单,在Person的空参构造器中加一条输出语句
执行之后如果控制台出现了输出语句,则说明调用了空参构造器
如果没有空参构造器就会报这个异常InstantiationException
IllegalAccessException表示非法访问,如果Person的空参构造器权限是私有的,就会报这个异常

要想此方法正常的创建运行时类的对象:要求
1.运行时类必须提供空参构造器
2.空参构造器的访问权限要满足要求
比如默认权限是在包内进行访问。通常设置为public
这也是javabean中要要求提供空参的权限为public的构造器的原因,反射有可能用到,便于通过反射创建运行时类的对象
还有一个原因是子类中的构造器如果没有显式的写super,相当于就是super()
如果不提供父类的空参构造器,这里就会报错
造对象都是用构造器去造的,也只有构造器才能够造对象,只是形式上有所区别

   @Test
    public void test() throws IllegalAccessException, InstantiationException {

        Class clazz=Person.class;

        Object obj = clazz.newInstance();//这个对象其实就是造的Person类的对象
        System.out.println(obj);//Person{name='null', age=0}

        //所以可以进行强制转换
        Person p=(Person)obj;
        //也可以用泛型,Class<Person> clazz=Person.class;//newInstance()返回值会自动识别为Person
        

    }

当然也可以调用指定的某个构造器;但是这种方式用的很少,用的比较多的还是直接newInstance(),再去操作属性

Constructor cons = clazz.getConstructor(String.class, int.class);//得到指定的构造器

反射的动态性:在运行代码时可以根据某些条件改变自身结构,比如说想创哪个类的对象,在编译时是定不下来的
如果是new构造器那对象就定下来了,所以必须通过反射的方式去写
所以框架中用到反射也是利用了反射的动态性

体会反射的动态性:

 //forName(String classPath);创建一个指定类的对象
    //classPath为指定类的全名
    
    public Object getInstance(String classPath) throws Exception {
        Class clazz = Class.forName(classPath);//得到Class实例

        return clazz.newInstance();//创建classPath所对应的类的实例

    }

    @Test
    public void test2(){
        int i = new Random().nextInt(3);//产生随机数,0,1,2中的任何一个
        String classPath ="";//不要写成 String classPath ;否则下面getInstance(classPath);报错,要进行初始化

        switch(i){
            case 0:
                classPath="java.util.Date";
                break;
            case 1:
                //classPath="java.sql.Date";不能用这个,没有空参构造器
                classPath="java.lang.Object";

                break;
            case 2:
                classPath="test.test01";//右键类名,点击copy reference,再ctrl+v
        }

        try {
            Object obj = getInstance(classPath);//编译完之后,并不能确定造哪个类的对象,是由运行后生成的随机数决定的
            System.out.println(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值