在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
s)String
- 作为声明中初始化的一部分的文字数组(数组没有构造函数)
- “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();