资讯专栏INFORMATION COLUMN

通过Class.newInstance()和Constructor.newInstance()两种反

dreamans / 2745人阅读

首先两种方式在源码里所在的位置

Class.newInstance() → Inside java.lang 包
Constructor.newInstance() → Inside java.lang.reflect 包

使用方法

Class.newInstance():

Class.forName("HelloWorld").newInstance();

或者

HelloWorld.class.newInstance();

Constructor.newInstance()

HelloWorld.class.getConstructor().newInstance();
二者区别
Class.newInstance()只能反射无参的构造器;
Constructor.newInstance()可以反任何构造器;

Class.newInstance()需要构造器可见(visible);
Constructor.newInstance()可以反私有构造器;

Class.newInstance()对于捕获或者未捕获的异常均由构造器抛出;
Constructor.newInstance()通常会把抛出的异常封装成InvocationTargetException抛出;

因为以上差异,所以很多框架使用的都是构造器反射的方式获取对象,像Spring, Guava, Zookeeper, Jackson, Servlet 等。

源码:

version:jdk1.8

直接类名反射实例化对象

@CallerSensitive
public T newInstance()
    throws InstantiationException, IllegalAccessException
{
    if (System.getSecurityManager() != null) {
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
    }

    // NOTE: the following code may not be strictly correct under
    // the current Java memory model.

    // Constructor lookup
    if (cachedConstructor == null) {
        if (this == Class.class) {
            throw new IllegalAccessException(
                "Can not call newInstance() on the Class for java.lang.Class"
            );
        }
        try {
            Class[] empty = {};
            final Constructor c = getConstructor0(empty, Member.DECLARED);
            // Disable accessibility checks on the constructor
            // since we have to do the security check here anyway
            // (the stack depth is wrong for the Constructor"s
            // security check to work)
            java.security.AccessController.doPrivileged(
                new java.security.PrivilegedAction() {
                    public Void run() {
                            c.setAccessible(true);
                            return null;
                        }
                    });
            cachedConstructor = c;
        } catch (NoSuchMethodException e) {
            throw (InstantiationException)
                new InstantiationException(getName()).initCause(e);
        }
    }
    Constructor tmpConstructor = cachedConstructor;
    // Security check (same as in java.lang.reflect.Constructor)
    int modifiers = tmpConstructor.getModifiers();
    if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
        Class caller = Reflection.getCallerClass();
        if (newInstanceCallerCache != caller) {
            Reflection.ensureMemberAccess(caller, this, null, modifiers);
            newInstanceCallerCache = caller;
        }
    }
    // Run constructor
    try {
        return tmpConstructor.newInstance((Object[])null);
    } catch (InvocationTargetException e) {
        Unsafe.getUnsafe().throwException(e.getTargetException());
        // Not reached
        return null;
    }
}

反射构造器实例化对象:

@CallerSensitive
public T newInstance(Object ... initargs)
    throws InstantiationException, IllegalAccessException,
           IllegalArgumentException, InvocationTargetException
{
    if (!override) {
        if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
            Class caller = Reflection.getCallerClass();
            checkAccess(caller, clazz, null, modifiers);
        }
    }
    if ((clazz.getModifiers() & Modifier.ENUM) != 0)
        throw new IllegalArgumentException("Cannot reflectively create enum objects");
    ConstructorAccessor ca = constructorAccessor;   // read volatile
    if (ca == null) {
        ca = acquireConstructorAccessor();
    }
    @SuppressWarnings("unchecked")
    T inst = (T) ca.newInstance(initargs);
    return inst;
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69920.html

相关文章

  • Java反射机制

    摘要:反射机制前言更多文章请一步本人博客网页版的的离线版什么是反射机制反射是语言的一个特性,它允程序在运行时注意不是编译的时候来进行自我检查并且对内部的成员进行操作。这个构造器就是用的反射在动态加载的时候来获取的中类的属性的。 Java反射机制 前言 更多文章请一步本人博客https://chenjiabing666.github.io/ 网页版的jdk的API 离线版API 什么是反射...

    wua_wua2012 评论0 收藏0
  • 进击的Android工程师之Java基础: 反射

    摘要:不包含父类或父接口的方法返回,根据方法名和类型获取。类或接口的及父类父接口公共成员方法。是的返回方法名,不包括修饰符,参数和返回值。打印打印抛出因为的访问权限为抛出,因为是父类的方法。 反射机制呢就是在程序运行时,动态的获取类(class),类的方法(method)属性(field)等。主要的注意点就是程序运行时动态的获取。这里主要是从代码的角度来讲解Java反射。在使用中我们用的较多...

    aaron 评论0 收藏0
  • Java中创建对象的5种不同方法

    摘要:使用关键字这是最常见的创建对象的方法,并且也非常简单。我们可以通过用以下方式创建对象或者使用构造函数类的方法与使用类的方法相似,类中有一个可以用来创建对象的函数方法。在反序列化中,虚拟机不会使用任何构造函数来创建对象。 作为Java开发者,我们每天都会创建大量的对象,但是,我们总是使用管理依赖系统(如Spring框架)来创建这些对象。其实还有其他方法可以创建对象,在接下来的文章中我会进...

    Bmob 评论0 收藏0
  • 万万没想到,JVM内存结构的面试题可以问的这么难?

    摘要:方法区在实际内存空间站可以是不连续的。这一规定,可以说是给了虚拟机厂商很大的自由。但是值得注意的是,堆其实还未每一个线程单独分配了一块空间,这部分空间在分配时是线程独享的,在使用时是线程共享的。 在我的博客中,之前有很多文章介绍过JVM内存结构,相信很多看多我文章的朋友对这部分知识都有一定的了解了。 那么,请大家尝试着回答一下以下问题: 1、JVM管理的内存结构是怎样的? 2、不同的...

    CloudwiseAPM 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<