JAVA创建对象的五种方式

Posted 古道子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA创建对象的五种方式相关的知识,希望对你有一定的参考价值。

最近在学习JAVA知识,通过网上翻看资料,发现原先有的理解不深的东西,渐渐明白了些。对象的使用,在编写软件过程中是必不可少的,不知道大家有没和我一样,几乎都是使用new来创建。那么,问题来了,JAVA有几种创建对象 的方式呢?

  • 使用new关键字创建。
  • 使用Class的newInstance()方法, 位于java.lang包,比如Person类,创建对象可以使用,但是下面的两种方式不能调用private构造函数,且构造对象的类中必须包含无参构造函数(构造器需可见 visible),否则会报错,对于捕获或者未捕获的异常均由构造器抛出;。
    public class person  {
        /**
         * 
         */
        private static final long serialVersionUID = 10L;
        String name = "Jack";
        public person(){
            this.name = name + " ma";
            System.out.println("construct Person");
        }
        
        private person(int a,int b) {
            System.out.println("a:"+a+ " b:" + b);
        }
        @Override
        public String toString() {
            return name;
        }
        
        
    }
    
    方法一
    //这里的testReflect为包名,Person类在此包下
    Class clazz = Class.forName("testReflect.person ");
    person p = (person ) clazz.newInstance();
    
    
    方法二
    person p =person .class.newInstance();

     

  • 使用Constructor类的newInstance方法,此方法属于反射,位于 java.lang.reflect 包,可以调用任何作用域的构造函数,private也可以,且创建对象的类构造函数可以任意。
    //调用无参构造函数 ,方式一
    person p = person.class.getDeclaredConstructor().newInstance();
    //调用无参构造函数 ,方式二
    Constructor c1=person.class.getDeclaredConstructor();
    c1.setAccessible(true);
    person p=(person)c1.newInstance();  

    这里大家思考下,在调用无参构造函数时,方式一和方式二有什么区别? 大家应该看到了c1.setAccessible(true); 这句代码吧,查看方法的定义包含如下:A value of true indicates that the reflected object should suppress Java language access checking when it is used,意思是为true的时候禁止验证授权,换句话的理解就是,private的无参构造也可以调用。这就是方式一和方式二的区别,方式一若private作用域修饰,则会报错。通常会把抛出的异常封装成InvocationTargetException抛出。

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

  •  

    //调用有参构造函数
    Constructor c1=person.class.getDeclaredConstructor(new Class[] {int.class,int.class});
    或
    Constructor  c1=person.class.getDeclaredConstructor(int.class,int.class);
    • public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
                                            throws NoSuchMethodException,
                                                   SecurityException
      • Parameters:
        parameterTypes - the parameter array
        Returns:
        The Constructor object for the constructor with the specified parameter list 
        传入参数为数组。

     

 

  • 使用Clone的方法:无论何时我们调用一个对象的clone方法,JVM就会创建一个新的对象,将前面的对象的内容全部拷贝进去,用clone方法创建对象并不会调用任何构造函数。要使用clone方法,创建对象的类必须实现Cloneable接口并实现其定义的clone方法。关于clone可参考我转载的JAVA深复制与浅复制
  • 使用反序列化:当我们序列化和反序列化一个对象,JVM会给我们创建一个单独的对象,在反序列化时,JVM创建对象并不会调用任何构造函数。为了反序列化一个对象,对应类需实现Serializable接口,附上一段具体实现代码。
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    public class People implements Serializable{
        private String name;
        public People(){
            this.name = "6点A君";
            System.out.println("construct people");
        }
        @Override
        public String toString() {
            return this.name;
        }
        
        public static void main(String[] args) {
            People p = new People();
            System.out.println(p);
            ObjectOutputStream oos = null;
            ObjectInputStream ois = null;
            try {
                FileOutputStream fos = new FileOutputStream("test.out");
                oos = new ObjectOutputStream(fos);
                oos.writeObject(p);
                oos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            People p1;
            try {
                FileInputStream fis = new FileInputStream("test.out");
                ois = new ObjectInputStream(fis);
                p1 = (People)ois.readObject();
                System.out.println(p1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

     

以上是关于JAVA创建对象的五种方式的主要内容,如果未能解决你的问题,请参考以下文章

JAVA创建对象的五种方式

java常见生成对象的五种方式

Carson带你学Java:解决生产者消费者问题的五种实现方式

Carson带你学Java:解决生产者消费者问题的五种实现方式

Carson带你学Java:解决生产者消费者问题的五种实现方式

Spring管理 hibernate 事务配置的五种方式