【问题标题】:Declaring Java object given its type/class name as string将 Java 对象给定为字符串类型/类名
【发布时间】:2011-01-14 18:41:03
【问题描述】:

我想知道是否可以在 Java 中声明某个给定类型的新对象,因为我已经将该类型表示为 Class 对象。

例如,假设我有

SomeClass obj1;
Class c = obj1.getClass();

现在我想使用“c”并用它来声明该类型的新对象。大致如下:

Class<c> my_new_var;

这样 my_new_var 将成为与 obj1 相同类型/类的变量。我想这与我们是否可以在新变量的声明中使用 Class 对象(或与该 Class 对象相关的东西)作为 type 直接相关。

由于 Java 是强类型,这可能还是不可能?

提前致谢,

布鲁诺

【问题讨论】:

  • 这种动态欺骗甚至在动态语言中是不鼓励的。为什么你认为这是个好主意?

标签: java class casting


【解决方案1】:
YourType newObject = c.newInstance();

但是你需要有一个无参数的构造函数。否则你必须做更多的反思。

请注意,如果您的 Class 已参数化,则无需强制转换。如果不是,就像在您的代码中那样,您需要一个演员表。

对于您的第二个问题 - 不,不可能声明动态类型的变量,因为是的,java 是静态类型的。您必须在编译时定义变量的类型。在上面的示例中,您可以:

  • 如果您不知道类型,请使用Object,因为它是所有对象的超类。
  • 使用泛型。例如(省略异常处理):

    public static <T> T createNewInstance(T exampleInstance) {
       return (T) exampleInstance.getClass().newInstance(); 
    }
    

【讨论】:

  • 假设你的类有一个公共的无参数构造函数。
  • 谢谢博卓。我知道 c.newInstance() 会给我一个与 obj1 相同类型的新对象;问题是在声明 newObject 时,我仍然需要将其声明为“YourType”,我认为除了通过“c”之外我不知道。理想情况下,我会发现在声明新变量时可以将 Class 之类的东西用作类型——这样我就可以执行 Class newObject = c.newInstance(),但我知道这可能是不可能的因为Java是静态类型的。我对吗?再次感谢!
  • 就像我在T(或Object)的第二个示例中一样,您可以推迟实际类型的声明。但在某些时候,您需要知道确切的类型。如果你不需要它(为了调用它的方法),那么你可以简单地将它称为Object
【解决方案2】:

如果你有默认构造函数:

SomeClass obj2 = (SomeClass) c.newInstance();

【讨论】:

  • 感谢阿德布拉。我了解您的解决方案,但请注意,在您的命令中,SomeClass 正是由 c 表示的类型/类,在这种情况下,我假设我不知道(通过 c 除外)。理想情况下,我想发现在声明新变量时可以将 Class 之类的东西用作类型——这样我就可以做 Class newObject = c.newInstance() 之类的事情,但我理解这可能是不可能的,因为 Java 是静态类型的。我对吗?再次感谢!
  • 在任何面向对象的语言中,您必须先知道某事物的类型,然后才能对其进行任何操作。在 Java 中,这可以是接口或基类,您可以强制转换为其中一个。在不知道其他任何事情的情况下,它只是一个对象,您几乎无能为力。
【解决方案3】:

像这样:

Class c  = Class.forName("com.xyzws.SomeClass"); 
Object a = c.newInstance();

【讨论】:

    【解决方案4】:

    my_new_var 将是 Class&lt;SomeClass&gt; 类型,这与 obj1 类型是 SomeClass 不同。

    但是my_new_var.newInstance() 确实为您提供了一个与obj1 类型相同的新对象。

    【讨论】:

      【解决方案5】:

      好吧,你可以这样做:

      SomeClass obj1 = ...
      Class<? extends SomeClass> c = obj1.getClass();
      SomeClass obj2 = c.newInstance();
      

      这需要在 SomeClass obj1 的任何子类(如果有)上使用无参数构造函数。

      但是,这仅在您知道所讨论的 Class 对象的类型时才有效。给定一些任意的原始ClassClass&lt;?&gt; 对象,您将不知道newInstance() 会返回什么类型的对象,并且您只能将该实例声明为Object

      【讨论】:

        【解决方案6】:

        是的,试试:

        那 a = c.newInstance();

        【讨论】:

          【解决方案7】:

          对我来说这很有效:

          Object innerObj = classObj.getClass().newInstance();
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-07-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-11-22
            相关资源
            最近更新 更多