在Java中创建对象的所有不同方法是什么?

时间:2008-09-18 18:35:17

标签: java

前几天与同事谈过此事。

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

22 个答案:

答案 0 :(得分:274)

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

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

 MyObject object = new MyObject();

<强>乙即可。使用Class.forName()
如果我们知道班级的名称&amp;如果它有一个公共默认构造函数,我们可以用这种方式创建一个对象。

MyObject object = (MyObject) Class.forName("subin.rnd.MyObject").newInstance();

<强> C 即可。使用clone()
clone()可用于创建现有对象的副本。

MyObject anotherObject = new MyObject();
MyObject object = (MyObject) anotherObject.clone();

<强> d 即可。使用object deserialization
对象反序列化只不过是从序列化形式创建对象。

ObjectInputStream inStream = new ObjectInputStream(anInputStream );
MyObject object = (MyObject) inStream.readObject();

您可以从here阅读。

答案 1 :(得分:66)

有多种方式:

  • 通过Class.newInstance
  • 通过Constructor.newInstance
  • 通过反序列化(使用派生程度最高的非可序列化基类的no-args构造函数)。
  • 通过Object.clone不会调用构造函数)。
  • 通过JNI(应该调用构造函数)。
  • 通过为您调用new的任何其他方法。
  • 我想你可以将类加载描述为创建新对象(例如实习String)。
  • 一个文字数组,作为声明中初始化的一部分(没有数组的构造函数)。
  • “varargs”(...)方法调用中的数组(没有数组的构造函数)。
  • 非编译时常量字符串连接(在典型实现中恰好产生至少四个对象)。
  • 导致运行时创建和抛出异常。例如throw null;"".toCharArray()[0]
  • 哦,原始拳击(除非缓存),当然。
  • JDK8应该有lambdas(本质上是简洁的匿名内部类),它们被隐式转换为对象。
  • 为了完整性(和PaŭloEbermann),还有一些new关键字的语法。

答案 2 :(得分:25)

在Java语言中,创建对象的唯一方法是通过调用其构造函数,无论是显式还是隐式。使用反射导致对构造函数方法的调用,反序列化使用反射来调用构造函数,工厂方法将调用包装到构造函数中以抽象实际构造,而克隆同样是一个包装构造函数调用。

答案 3 :(得分:13)

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

答案 4 :(得分:10)

在Java中创建对象有五种不同的方法,

<强> 1。使用new关键字→构造函数调用

Employee emp1 = new Employee();

<强> 2。使用newInstance()Class方法→构造函数调用

Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee")
                                .newInstance();

它也可以写成

Employee emp2 = Employee.class.newInstance();

第3。使用newInstance() Constructor方法→构造函数调用

Constructor<Employee> constructor = Employee.class.getConstructor();
Employee emp3 = constructor.newInstance();

<强> 4。使用clone()方法→无构造函数调用

Employee emp4 = (Employee) emp3.clone();

<强> 5。使用反序列化→没有构造函数调用

ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
Employee emp5 = (Employee) in.readObject();

前三个方法new关键字和newInstance()都包含构造函数调用,但后来有两个克隆和反序列化方法在不调用构造函数的情况下创建对象。

以上所有方法都有不同的字节码,例如,阅读Different ways to create objects in Java with Example以及更详细的描述,例如:所有这些方法的字节码转换。

然而,人们可以争辩说创建数组或字符串对象也是创建对象的一种方式,但这些事情仅对某些类更具体并由JVM直接处理,而我们可以通过使用这些来创建任何类的对象5种方式。

答案 5 :(得分:9)

答案 6 :(得分:6)

有一种对象,它不能由普通实例创建机制(调用构造函数)构造:数组。使用

创建数组
 A[] array = new A[len];

 A[] array = new A[] { value0, value1, value2 };
正如Sean在评论中所说,这在语法上类似于构造函数调用,在内部它只不过是分配和零初始化(或用显式内容初始化,在第二种情况下)一个内存块,带有一些头表明类型和长度。

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

第四种方式是

 A[] array = (A[]) Array.newInstance(A.class, len);

当然,克隆和反序列化也适用于此。

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

答案 7 :(得分:6)

您也可以使用

 Object myObj = Class.forName("your.cClass").newInstance();

答案 8 :(得分:6)

如果您不熟悉java,每个对象都继承自Object

,那么应该注意这一点

protected native Object clone()抛出CloneNotSupportedException;

答案 9 :(得分:6)

此外,您可以反序列化数据到对象中。这不是通过类构造函数!


更新:感谢Tom在评论中指出这一点!迈克尔也试验过。

  

它遍历派生最多的非可序列化超类的构造函数   当该类没有no-args构造函数时,在反序列化时抛出InvalidClassException。

请参阅汤姆的回答,以便对所有病例进行全面治疗;-)
is there any other way of creating an object without using "new" keyword in java

答案 10 :(得分:5)

如果我们是详尽无遗的其他方式。

  • 在Oracle JVM上是Unsafe.allocateInstance(),它在不调用构造函数的情况下创建实例。
  • 使用字节码操作,您可以将代码添加到anewarraymultianewarraynewarraynew。可以使用诸如ASM或BCEL之类的库来添加这些。 Oracle的Java附带了一个版本的bcel。同样,这不会调用构造函数,但您可以将构造函数称为单独调用。

答案 11 :(得分:4)

反射:

someClass.newInstance();

答案 12 :(得分:4)

  • 使用new运算符(从而调用构造函数)
  • 使用反射clazz.newInstance()(再次调用构造函数)。或者clazz.getConstructor(..).newInstance(..)(再次使用构造函数,但您可以选择哪一个)

通过调用对象类的构造函数来总结答案 - 一种主要方式。

更新:另一个答案列出了两种不涉及使用构造函数的方法 - deseralization和cloning。

答案 13 :(得分:4)

反思也将为你完成这项工作。

SomeClass anObj = SomeClass.class.newInstance();

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

答案 14 :(得分:3)

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

Foo fooClone = fooOriginal.clone (); 

答案 15 :(得分:3)

在Java中创建对象有五种不同的方法:

1。使用`new`关键字:

这是在Java中创建对象的最常用方法。几乎99%的对象都是以这种方式创建的。

MyObject object = new MyObject();//normal way

2。使用工厂方法:

ClassName ObgRef=ClassName.FactoryMethod();

示例:

RunTime rt=Runtime.getRunTime();//Static Factory Method

3。通过使用克隆概念:

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

MyObjectName anotherObject = new MyObjectName();
MyObjectName object = anotherObjectName.clone();//cloning Object

4。使用`Class.forName()`:

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

MyObjectName object = (MyObjectNmae) Class.forName("PackageName.ClassName").newInstance();

示例:

String st=(String)Class.forName("java.lang.String").newInstance();

5。使用对象反序列化:

对象反序列化只不过是从序列化形式创建一个对象。

ObjectInputStreamName inStream = new ObjectInputStreamName(anInputStream );
MyObjectName object = (MyObjectNmae) inStream.readObject();

答案 16 :(得分:2)

方法1

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

Employee object = new Employee();

方法2

使用Class.forName()。 Class.forName()为您提供了类对象,它对于反射非常有用。此对象具有的方法由Java定义,而不是由编写类的程序员定义。每个班级都是一样的。调用newInstance()会给你一个该类的实例(即callingClass.forName(&#34; ExampleClass&#34;)。newInstance()它相当于调用new ExampleClass()),你可以在其上调用方法该类定义,访问可见字段等。

Employee object2 = (Employee) Class.forName(NewEmployee).newInstance();

Class.forName()将始终使用调用者的ClassLoader,而ClassLoader.loadClass()可以指定不同的ClassLoader。我相信Class.forName也会初始化加载的类,而ClassLoader.loadClass()方法不会立即执行此操作(直到第一次使用它才会初始化)。

另一个必读:

Java:线程状态简介与示例 简单的Java枚举示例

方法3

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

Employee secondObject = new Employee();
Employee object3 = (Employee) secondObject.clone();

方法4

使用newInstance()方法

Object object4 = Employee.class.getClassLoader().loadClass(NewEmployee).newInstance();

方法5

使用对象反序列化。对象反序列化只不过是从序列化形式创建对象。

// 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();

答案 17 :(得分:0)

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

答案 18 :(得分:-1)

完全取决于你的意思,但其他一些是:

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

答案 19 :(得分:-2)

还有ClassLoader.loadClass(s​​tring),但这种情况并不经常使用。

如果你想成为一名完整的律师,由于数组的.length属性,数组是技术上对象。所以初始化一个数组会创建一个对象。

答案 20 :(得分:-3)

我们可以用5种方式创建对象:

  1. 由新运营商
  2. 通过反射(例如Class.forName()后跟Class.newInstance())
  3. 按工厂方法
  4. 通过克隆
  5. by reflection api

答案 21 :(得分:-5)

我们也可以用这种方式创建对象: -

String s ="Hello";

没人讨论过。