答疑 | Java中五种创建对象的方式,SSDB

 

创建对象的几种方式

1.除了new以外,还有哪些创建对象的方式呢?

 

答:在java中,可以通过以下几种方式创建一个对象。

(1)new 构造方法() ;

(2)使用newInstance()方法,此方法的返回值就是一个对象。不过,需要注意的是,在JDK的java.lang.reflect.Constructor和java.lang.Class两个类中,都存在着newInstance()方法,这两个newInstance()方法都可以用于创建对象,其源码如下所示。

①Class类中的newInstance()

public final class Class implements java.io.Serializable,
                              GenericDeclaration,
                              Type,
                              AnnotatedElement {
    ...
    @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;
        }
    }

}

 

②Constructor类中的newInstance()

public final class Constructor extends Executable {
    ...
    @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;
    }
}

 

(3)使用Object提供的clone()方法 【clone()会在jvm中创建一个新的对象】。其源码如下所示。

public class Object {
    ...
    protected native Object clone() throws CloneNotSupportedException;
}

 

(4)使用对象流(ObjectInputStream)的readObject()方法,实际就是一个反序列化操作,其源码如下所示。

public class ObjectInputStream
    extends InputStream implements ObjectInput, ObjectStreamConstants
{
   ...
      public final Object readObject()
        throws IOException, ClassNotFoundException
    {
        if (enableOverride) {
            return readObjectOverride();
        }

        // if nested read, passHandle contains handle of enclosing object
        int outerHandle = passHandle;
        try {
            Object obj = readObject0(false);
            handles.markDependency(outerHandle, passHandle);
            ClassNotFoundException ex = handles.lookupException(passHandle);
            if (ex != null) {
                throw ex;
            }
            if (depth == 0) {
                vlist.doCallbacks();
            }
            return obj;
        } finally {
            passHandle = outerHandle;
            if (closed && depth == 0) {
                clear();
            }
        }
    }
}

 

(5)JVM隐式操作

JVM底层也会帮我们隐式的创建一些对象,最常见的就是JVM方法区中常量池里的对象了。例如,当我们编写 String str = "abc"时,在String常量池中就会创建一个"abc"对象。

 

好,最后总结一下在Java中创建对象的方式:

(1)new;

(2)- (3)使用java.lang.reflect.Constructor或java.lang.Class类中的newInstance()方法;

(4)使用对象流(ObjectInputStream)的readObject()方法;

(5)JVM隐式操作;
 

缓存只有Redis吗?

2.老师,每次一说到缓存中间件,就会提到Redis。那么,还有其他常用的缓存中间件吗?

 

答:除了Redis以外,目前SSDB也是一款流行的缓存中间件。SSDB是基于google levelDB 存储引擎,它的最大的特点是将数据直接缓存到硬盘上(Redis是缓存在内存中),因此使用SSDB不用考虑内存容量问题。非常值得注意的是:虽然 SSDB 是将数据缓存在硬盘,但却与Redis的读写性能却相差不远(一般而言,读性能,SSDB > Redis ;写性能,Redis > SSDB )。

SSDB 还支持主从同步、负载均衡和持久化队列等特性,并且 SSDB 在设计时就考虑到了与 Redis 的兼容问题,兼容 Redis API,甚至支持使用Redis客户端访问 SSDB 。

 

 

- 完 -

推荐阅读

Java小白到大神的心路历程(Java SE)

答疑 | 面试全对,却没offer?

答疑 | 背下这300字,面试就能加薪!

你可能感兴趣的:(答疑 | Java中五种创建对象的方式,SSDB)