美文网首页
利用construct.newInstance()生成实例

利用construct.newInstance()生成实例

作者: Crazy贵子 | 来源:发表于2018-10-08 10:11 被阅读0次

在使用反射生成泛型的具体对象实例时发现没有达到自己的预期目的,所以研究了一下constructor.newInstance()方法。我的问题是在创建具体类型传给反射使用时,会出现找不到相应构造函数的情况。

利用反编译查看发现外部类和内部类调用构造函数时传入的参数是不一样的,以下是讲解的例子。

首先声明三个类:非静态内部类,静态内部类,布局内部类。


public class InnerClass {

    // 非静态内部类
    class InnerA {
        private String name;

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

        public InnerA() {}
    }

    // 静态内部类
    static class InnerB {
        private String name;

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

        public InnerB() {}
    }

    private void show() {

        // 局部内部类
        class InnerC {
            private String name;

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

            public InnerC() {}
        }
    }
}

反编译后生成4个class文件:

  • InnerClass.class
  • InnerClass$InnerA.class
  • InnerClass$InnerB.class
  • InnerClass$1InnerC.class

利用javap -c命令查看三个内部类发现其构造方法如下:

InnerA.class InnerB.class 1InnerC.class

由上可以发现,当这个实例的类是静态内部类时第一个参数不需要传入外部类,如果是非静态内部类和局部内部类第一个参数则需要传入外部类。

在弄明白这个情况后,当我们调用getDeclaredConstructor()newInstance()方法时就能根据这个实例的类所在的位置而针对第一个参数做相应的调整了。

其调整如下:

  • 如果实例的类是外部类和静态内部类,第一个参数不用考虑
  • 如果实例的类是非静态内部类和局部内部类,第一个参数需要传入这个类所在的外部类。

如何判断一个类是外部类还是内部类或者是局部内部类呢?可以利用class提供的方法,也可以配合Modifier这个类使用。

class modifier

利用以上方法可以根据不同的情况调用不同方法:

        // 非静态内部类和局部内部类
        if (z.isLocalClass() || !Modifier.isStatic(z.getModifiers()) && z.isMemberClass()) {
            try {
                constructor = z.getDeclaredConstructor(getClass(), String.class);
                object = constructor.newInstance(this, s);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        } else { // 外部类和静态内部类
            try {
                constructor = z.getDeclaredConstructor(String.class);
                object = constructor.newInstance(s);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }

相关文章

  • 利用construct.newInstance()生成实例

    在使用反射生成泛型的具体对象实例时发现没有达到自己的预期目的,所以研究了一下constructor.newInst...

  • MySQL行转列实现和总结

    一、行转列实例 1、准备数据 最终想要的结果是这样: 2、利用SUM(IF()) 生成列 3,利用max(CASE...

  • Axis2创建WebService实例

    利用wsdl2java工具生成webservice的客户端代码 Axis2创建WebService实例

  • express 使用笔记1

    创建app.js文件 Express 应用生成器 路由实例 利用 Express 托管静态文件 通过 Expres...

  • 【SpringBoot DB系列】Mybatis-Plus 代码

    【SpringBoot DB系列】Mybatis-Plus 代码自动生成 一个简单的实例工程,介绍利用 mybat...

  • 手写Retrofit

    遇到的坑:1、反射自动生成实例的坑。Proxy.newProxyInstance()首先,利用反射获取类方法是运行...

  • KVO与KVC原理

    KVO 1:实现原理 对实例对象属性监听,会利用runtime动态生成一个类NSKVONotifying_Clas...

  • Factory Method模式(设计模式)

    父类决定实例的生成方式,但不决定要生成的具体的类,具体的处理全部交给子类负责。 将生成实例的框架和实际负责生成实例...

  • JavaScript 面向对象的那些事儿

    一、类与实例 1、类的声明 2、生成实例 生成实例,都是用new方法,如下: 二、类与继承 JavaScript的...

  • JavaScript(三)(对象/原型/继承)

    封装:将属性和方法封装进对象 构造函数:函数中有this指向对象 从构造函数生成实例: 生成实例的时候,为每个实例...

网友评论

      本文标题:利用construct.newInstance()生成实例

      本文链接:https://www.haomeiwen.com/subject/uzddaftx.html