当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《在Java中创建对象的所有不同方法是什么?》经验,为你挑选了11个好方法。

前几天与同事谈过此事.

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



1> kamaci..:

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

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

 MyObject object = new MyObject();

.使用Class.forName()
如果我们知道类的名称并且它是否有公共默认构造函数,我们可以用这种方式创建一个对象.

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

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

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

d.使用object deserialization
对象反序列化只不过是从序列化形式创建对象.

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

你可以在这里阅读


@AlexR:`Object.clone()`也不调用构造函数.
所以实际上只存在两种方式:调用构造函数(使用new,clone()或反射)和不调用构造函数的反序列化.
您还应该提到`Constructor`类,它概括了`Class.newInstance`.

2> Tom Hawtin -..:

有各种方法:

通过Class.newInstance.

通过Constructor.newInstance.

通过反序列化(使用最派生的非可序列化基类的no-args构造函数).

通过Object.clone(不调用构造函数).

通过JNI(应该调用构造函数).

通过任何其他方法new为您调用.

我猜你可以将类加载描述为创建新对象(例如interned Strings).

作为声明中初始化的一部分的文字数组(没有数组的构造函数).

"varargs"(...)方法调用中的数组(没有数组的构造函数).

非编译时间常量字符串连接(在典型的实现中恰好产生至少四个对象).

导致运行时创建和抛出异常.例如throw null;"".toCharArray()[0].

当然,哦,原始拳击(除非缓存).

JDK8应该有lambda(基本上是简洁的匿名内部类),它们被隐式转换为对象.

为了完整性(和PaŭloEbermann),new关键字也有一些语法.


您也应该添加"正常方式":-)
你错过了一个:`java.misc.Unsafe.allocateInstance()`.虽然这有很多原因令人讨厌.实际上,反序列化不使用no-args构造函数.在引擎盖下它使用`allocateInstance`或等效的黑魔法.

3> Confusion..:

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


我不应该写'它的构造函数'和'构造函数',而是'构造函数'和'构造函数'.在反序列化的情况下,始终调用第一个适用的no-arg构造函数.

4> Thomas Lötze..:

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


是的,在许多情况下可以抛出异常.有关可能出错的示例,请参阅JavaDoc for newInstance().

5> Naresh Joshi..:

在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 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()包含构造函数调用,但后来两个克隆和反序列化方法创建对象而不调用构造函数.

所有上述方法都有不同的字节码与它们相关,阅读不同的方式来创建Java中的对象,例如示例和更详细的描述,例如所有这些方法的字节码转换.

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



6> Bill the Liz..:

克隆和反序列化.



7> Vincent Ramd..:

你也可以使用

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



8> stacker..:

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

protected native clone clone()抛出CloneNotSupportedException;


@ryanprayogo clone()将返回一个新对象(即使该对象是clone()被调用的对象的克隆),实际上是在没有调用构造函数的情况下创建新对象的唯一方法.

9> KLE..:

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


更新:感谢汤姆在你的评论中指出这一点!迈克尔也进行了实验.

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

请参阅Tom的答案以获得对所有情况的完整处理;-)
是否还有其他方法可以在java中创建对象而不使用"new"关键字



10> Paŭlo Eberma..:

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

 A[] array = new A[len];

要么

 A[] array = new A[] { value0, value1, value2 };

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

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

第四种方式

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

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

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



11> Peter Lawrey..:

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

在Oracle JVM上是Unsafe.allocateInstance(),它在不调用构造函数的情况下创建实例.

使用字节码操作,你可以添加代码anewarray,multianewarray,newarraynew.可以使用诸如ASM或BCEL之类的库来添加这些.Oracle的Java附带了一个版本的bcel.同样,这不会调用构造函数,但您可以将构造函数称为单独调用.

推荐阅读
php
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有