用Java创建对象的所有不同方式有哪些?

时间:2020-03-06 14:22:49  来源:igfitidea点击:

前几天与同事进行了一次交谈。

有一个明显的方法是使用构造函数,但是还有哪些其他方法呢?

解决方案

克隆和反序列化。

反射:

someClass.newInstance();

完全取决于我们要创建的含义,但其他一些含义是:

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

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

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

也有ClassLoader.loadClass(s​​tring),但这并不经常使用。

如果我们想成为一名全面的律师,由于数组的.length属性,数组在技术上是对象。因此初始化数组会创建一个对象。

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

你也可以用

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

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

SomeClass anObj = SomeClass.class.newInstance();

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

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

受保护的本机对象clone()抛出CloneNotSupportedException;

另外,我们可以将数据反序列化为对象。这不会通过类Constructor进行!

更新:感谢汤姆在评论中指出了!迈克尔也做了实验。

It goes through the constructor of the most derived non-serializable superclass.

  And when that class has no no-args constructor, a InvalidClassException is thrown upon de-serialization.

请参阅汤姆的回答以完整了解所有情况;-)
还有什么其他方法可以在不使用Java中使用" new"关键字的情况下创建对象

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

Foo fooClone = fooOriginal.clone ();

有多种方法:

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