【问题标题】:how to know which constructor was used in creating an object?如何知道创建对象时使用了哪个构造函数?
【发布时间】:2009-10-05 00:45:15
【问题描述】:

考虑

Class A has two constructors new A(int), new A(int, String)

还有

it has a method show()

然后给出一个类似的语句,

A a1= new A(4);
A a2= new A(3, "foo");

后来在代码中(或在传递这些对象的某些方法中)

a1.show();
a2.show();
new A(3).show();
and 
new A(2,"bar").show();

如果我想根据对象(a1 和 a2)以及类实例表达式(直接在构造函数上调用 show)来区分这些 show 方法,并且不知道使用了哪个构造函数(尤其是对象 a1和 a2) 我如何找到答案——反思地说?

【问题讨论】:

  • 这听起来像是“我真的不知道你为什么要这样做,但这是一个坏主意”的情况之一。如果可以,您可能需要澄清并添加一些细节。
  • 另外,如果这可能的话,我们需要知道你在说什么语言。 C#? C++? Javascript?爪哇?
  • 这样做的目的是什么?看起来这是一个“标记”类,可能应该分为 2 个类。更多信息会给出更好的答案。

标签: java reflection object constructor


【解决方案1】:

做到这一点的唯一方法是让每个构造函数设置一个不同的变量来指示它已被使用。

但我同意汤姆的观点;这听起来是个坏主意。你如何创建一个对象无关紧要(因为构造函数甚至可能根本没有被使用过,比如说,在序列化中),它的所有属性(公共或非公共)都被正确设置以反映状态应该很重要它需要在里面。

【讨论】:

    【解决方案2】:

    也许 A 应该是两个不同的类(每个都有不同的构造函数);或公共基类的两个不同子类:这样,每个类都可以有自己不同的 show 方法实现。

    或者,在 A 内部有一个数据成员(可能是布尔值或字符串),其值由每个构造函数设置不同。

    【讨论】:

    • 请注意,可能并不总是调用构造函数来创建对象,因此此解决方案通常不起作用。
    • silky:请问,您如何在 Java 中创建对象而不调用其构造函数?
    • R:公平地说,当我评论说海报没有确认语言时;我不是普通的 Java 用户,但有人暗示我可以通过 sun.misc.Unsafe 实现这一点。需要进一步研究;随时执行并报告:)
    【解决方案3】:

    如果两个类有不同的行为集,那么它们就是两个不同的类。单个类的行为不应因构建方式而异。

    【讨论】:

      【解决方案4】:

      同意你最好使用两个单独的类,在这种情况下你可以使用多态性(C#中的例子),

      public class Base
      {
          public BaseClass()
          public virtual void Show
          {
              // show stuff
          }
      }
      
      public class A : Base
      {
          public A(int i)
          public override void Show()
          {
              // show A stuff
          }
      }
      
      public class B : Base
      {
          public B(int i, String s)
          public override void Show()
          {
              // show B stuff
          }
      }
      

      然后调用类

      Base a1= new A(4);
      Base a2= new B(3, "foo");
      

      并且应该很容易根据 a1 和 a2 对象区分这些显示方法。

      【讨论】:

        【解决方案5】:

        无法通过反射确定使用哪个构造函数来实例化对象。为什么不在每个构造函数中简单地将实例变量设置为不同的值,以跟踪调用了哪个?

        【讨论】:

          【解决方案6】:

          所以调用 show 的四种方式都应该执行不同的操作?

          每个动作的原因和区别是什么?

          在没有更多了解的情况下,我们只能做出疯狂的猜测。这听起来确实像是两个甚至四个类(加上一个基类/接口)和一个创建它们的工厂的工作。

          如果问题纯粹是理论上的 - 不,您无法在运行时区分:

          A a = new A();
          a.show();
          

          new A().show();
          

          这样做的唯一方法是检查源¹,因此您必须包含源并在包含完整源编号的情况下进行编译。解析源代码以找出它是如何被调用的。

          【讨论】:

            猜你喜欢
            • 2011-01-29
            • 1970-01-01
            • 1970-01-01
            • 2011-06-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-08-16
            • 1970-01-01
            相关资源
            最近更新 更多