Java 使用“创建”创建的对象;新";关键字并使用反射创建

Java 使用“创建”创建的对象;新";关键字并使用反射创建,java,reflection,Java,Reflection,我开始知道,使用反射我们可以创建对象,而不必使用“new”关键字。所以我想知道它们之间有什么区别,或者使用反射的任何特定场景。因为到现在为止,我还没有创建或看到任何使用反射创建对象的代码 为什么使用“new”变得如此常用,而反射却没有使用。只有当您想基于名称(字符串)实例化一个类型,或者在编译时无法访问的类型(例如插件)时,才使用反射。在正常情况下,您不想用它来代替new来实例化类型。反射通常比简单的代码慢得多,也更繁琐。它不是常规代码的替代品(就像一个新的操作符),而是无法使用常规代码的情况下

我开始知道,使用反射我们可以创建对象,而不必使用“new”关键字。所以我想知道它们之间有什么区别,或者使用反射的任何特定场景。因为到现在为止,我还没有创建或看到任何使用反射创建对象的代码


为什么使用“new”变得如此常用,而反射却没有使用。

只有当您想基于名称(字符串)实例化一个类型,或者在编译时无法访问的类型(例如插件)时,才使用反射。在正常情况下,您不想用它来代替
new
来实例化类型。

反射通常比简单的代码慢得多,也更繁琐。它不是常规代码的替代品(就像一个新的操作符),而是无法使用常规代码的情况下的替代品。

Mehrdad是正确的。当您需要在运行时而不是编译时执行某些操作时,可以使用反射。可能您需要执行的方法直到运行时才知道,或者对象类型不知道。插件就是一个很好的例子

反射确实会导致性能下降,这就是为什么您应该尝试将其限制在新功能不适用于您的情况下

为什么使用“新”变得如此常用和 反思不是

与“new”关键字相比,使用reflection需要做大量的工作;它还导致可读性较差的代码


当由于某种原因,实例化对象的代码无法知道该对象的具体类型时,可以使用反射。反射在中被广泛使用。

在spring框架中有一个更真实的例子说明了这种用法。其中,我们将在xml中定义对象及其协作类的依赖项,容器将实际使用反射创建它们的实例,甚至使用反射调用生命周期方法并移交创建的对象。这是您将使用的一个典型场景。另外,如果您查看大多数BRMS解决方案,它们使用反射在运行时使用反射触发业务规则方法。尽管现实世界中每天使用反射来创建对象的情况很少,但使用某种反射的另一个地方是使用JDBC(Class.forName(“driver Class”)。

假设您希望使用一个构造函数来实例化类
MyObject
,该构造函数使用一个
String
类型的参数。使用
新建

MyObject myObject = new MyObject("constructor-arg1");
带着沉思:

Constructor constructor = MyObject.class.getConstructor(String.class);

MyObject myObject = (MyObject) constructor.newInstance("constructor-arg1");
(例如从中被盗)

它应该比前者更清晰,可读性更强,打字速度更快。此外,反思往往慢得令人痛苦。另一方面,反射允许在编译时实例化对象而不知道它们的类


总之,只有在没有其他选择时才使用反射…

支持
新的

MyObject myObject = new MyObject("constructor-arg1");
  • 它比反射快得多
  • 这会导致代码更干净,更易于维护
  • 反射不是类型安全的
  • 由于#3,支持重构的IDE(如Eclipse)无法很好地处理反射
  • 有利于反思:

    Constructor constructor = MyObject.class.getConstructor(String.class);
    
    MyObject myObject = (MyObject) constructor.newInstance("constructor-arg1");
    
  • 当您不知道要在编译时实例化的类的类型时,这是唯一的选项
  • 如您所见,
    new
    是您希望在99%的情况下使用的。反射在某些框架内使用,如模拟对象框架、依赖项注入框架或服务提供者接口(SPI)。在大多数情况下,您将是这些内容的用户,但不是自己编写


    顺便说一句,如果您仍然想使用反射,那么有一些工具可以让通过反射实例化对象的过程变得不那么痛苦:我想到了。

    我甚至可以说,在其他任何时候都不要使用它。它会造成不必要的混乱和脆弱。@Alex:的确如此。它们实际上并不具有可比性。意味着做不同的事情。