在Java中创建对象有哪些不同的方法?

在Java中创建对象有哪些不同的方法?,java,Java,前几天我和一个同事谈过这件事 使用构造函数是显而易见的,但是还有什么其他方法呢?和。反射: someClass.newInstance(); 具体取决于您所说的“创建”是什么意思,但其他一些是: 克隆法 反序列化 反射(Class.newInstance()) 反射(构造函数对象) 在Java语言中,创建对象的唯一方法是显式或隐式调用其构造函数。使用反射导致调用构造函数方法,反序列化使用反射调用构造函数,工厂方法包装调用构造函数以抽象实际构造,克隆类似于包装构造函数调用。从API用户的角度来

前几天我和一个同事谈过这件事

使用构造函数是显而易见的,但是还有什么其他方法呢?

和。

反射:

someClass.newInstance();

具体取决于您所说的“创建”是什么意思,但其他一些是:

  • 克隆法
  • 反序列化
  • 反射(Class.newInstance())
  • 反射(构造函数对象)

    • 在Java语言中,创建对象的唯一方法是显式或隐式调用其构造函数。使用反射导致调用构造函数方法,反序列化使用反射调用构造函数,工厂方法包装调用构造函数以抽象实际构造,克隆类似于包装构造函数调用。

      从API用户的角度来看,构造函数的另一种替代方法是静态工厂方法(如biginger.valueOf()),不过对于API作者(从技术上说是“真实的”)来说,对象仍然是使用构造函数创建的。

      还有ClassLoader.loadClass(string),但这并不常用


      如果你想成为这方面的律师,数组在技术上是对象,因为数组的.length属性。因此初始化数组会创建一个对象。

      是的,可以使用反射创建对象。例如,
      String.class.newInstance()
      将为您提供一个新的空字符串对象。

      您还可以使用

       Object myObj = Class.forName("your.cClass").newInstance();
      
      MyObject anotherObject = new MyObject();
      MyObject object = (MyObject) anotherObject.clone();
      
      MyObjectName anotherObject = new MyObjectName();
      MyObjectName object = anotherObjectName.clone();//cloning Object
      
      Employee secondObject = new Employee();
      Employee object3 = (Employee) secondObject.clone();
      

      反思也能帮你完成这项工作

      SomeClass anObj = SomeClass.class.newInstance();
      

      是创建类的新实例的另一种方法。在这种情况下,您还需要处理可能引发的异常。

      如果您是java新手,应该注意到这一点,每个对象都继承自对象


      受保护的本机对象克隆()引发CloneNotSupportedException

      此外,还可以将数据反序列化到对象中。这不是通过类构造函数实现的


      更新:感谢Tom在您的评论中指出这一点!迈克尔也做了实验

      它通过最派生的不可序列化超类的构造函数执行。
      当该类没有参数构造函数时,反序列化时会引发InvalidClassException

      关于所有病例的完整处理,请参见Tom的答案;-)

      您还可以克隆现有对象(如果它实现了可克隆)


      有多种方式:

      • 通过
        Class.newInstance
      • 通过
        构造函数.newInstance
      • 通过反序列化(使用派生最多的不可序列化基类的无参数构造函数)
      • 通过
        Object.clone
        不调用构造函数)
      • 通过JNI(应该调用构造函数)
      • 通过为您调用
        new
        的任何其他方法
      • 我想您可以将类加载描述为创建新对象(例如interned
        String
        s)
      • 作为声明中初始化的一部分的文字数组(数组没有构造函数)
      • “varargs”(
        )方法调用中的数组(数组没有构造函数)
      • 非编译时常量字符串串联(在典型实现中,至少会生成四个对象)
      • 导致运行时创建并引发异常。例如
        抛出null
        “”。ToCharray()[0]
      • 当然,还有原语的装箱(除非缓存)
      • JDK8应该有lambda(本质上是简洁的匿名内部类),它们被隐式转换为对象
      • 为了完整性(还有帕罗·埃伯曼),还有一些带有
        new
        关键字的语法
          • 使用
            new
            操作符(从而调用构造函数)
          • 使用反射
            clazz.newInstance()
            (再次调用构造函数)。或者通过
            clazz.getConstructor(..).newInstance(..)
            (同样使用构造函数,但您可以选择哪一个)
          通过调用对象类的构造函数来总结答案(一种主要方法)


          更新:另一个答案列出了两种不涉及使用构造函数的方法-反序列化和克隆

          在java中创建对象有四种不同的方法:

          A。使用
          new
          关键字
          这是在java中创建对象最常用的方法。几乎99%的对象都是以这种方式创建的

           MyObject object = new MyObject();
          
          MyObject object = (MyObject) Class.forName("subin.rnd.MyObject").newInstance();
          
          MyObject object = new MyObject();//normal way
          
          MyObjectName object = (MyObjectNmae) Class.forName("PackageName.ClassName").newInstance();
          
          Employee object = new Employee();
          
          B。使用
          Class.forName()

          如果我们知道类的名称&如果它有一个公共的默认构造函数,我们可以用这种方式创建一个对象

           MyObject object = new MyObject();
          
          MyObject object = (MyObject) Class.forName("subin.rnd.MyObject").newInstance();
          
          MyObject object = new MyObject();//normal way
          
          MyObjectName object = (MyObjectNmae) Class.forName("PackageName.ClassName").newInstance();
          
          Employee object = new Employee();
          
          C。使用
          clone()

          clone()可用于创建现有对象的副本

          MyObject anotherObject = new MyObject();
          MyObject object = (MyObject) anotherObject.clone();
          
          MyObjectName anotherObject = new MyObjectName();
          MyObjectName object = anotherObjectName.clone();//cloning Object
          
          Employee secondObject = new Employee();
          Employee object3 = (Employee) secondObject.clone();
          
          D。使用对象反序列化

          对象反序列化只不过是从其序列化形式创建对象

          ObjectInputStream inStream = new ObjectInputStream(anInputStream );
          MyObject object = (MyObject) inStream.readObject();
          
          ObjectInputStreamName inStream = new ObjectInputStreamName(anInputStream );
          MyObjectName object = (MyObjectNmae) inStream.readObject();
          
          // Create Object5
          // create a new file with an ObjectOutputStream
          FileOutputStream out = new FileOutputStream("");
          ObjectOutputStream oout = new ObjectOutputStream(out);
          
          // write something in the file
          oout.writeObject(object3);
          oout.flush();
          
          // create an ObjectInputStream for the file we created before
          ObjectInputStream ois = new ObjectInputStream(new FileInputStream("crunchify.txt"));
          Employee object5 = (Employee) ois.readObject();
          

          您可以从中读取它们。

          存在一种类型的对象,它不能由正常的实例创建机制(调用构造函数)构造:数组。数组是用

           A[] array = new A[len];
          

          正如Sean在一篇评论中所说,这在语法上类似于构造函数调用,在内部它只不过是分配和零初始化(或在第二种情况下使用显式内容初始化)内存块,并带有一些头来指示类型和长度

          将参数传递给varargs方法时,也会隐式创建(并填充)数组

          第四种方法是

           A[] array = (A[]) Array.newInstance(A.class, len);
          
          当然,克隆和反序列化在这里也起作用


          标准API中有许多创建数组的方法,但实际上它们都在使用这些方法中的一种(或多种)。

          如果我们详尽无遗的话,还有其他方法

          • 在Oracle JVM上是不安全的。allocateInstance()创建实例时不调用构造函数
          • Employee emp1 = new Employee();
            Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee")
                                            .newInstance();
            
            Employee emp2 = Employee.class.newInstance();
            
            Constructor<Employee> constructor = Employee.class.getConstructor();
            Employee emp3 = constructor.newInstance();
            
            Employee emp4 = (Employee) emp3.clone();
            
            ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
            Employee emp5 = (Employee) in.readObject();