【问题标题】:Do we need the method getClass() from java.lang.Object?我们需要来自 java.lang.Object 的方法 getClass() 吗?
【发布时间】:2011-11-15 22:04:17
【问题描述】:

我知道java.lang.Object 中的getClass() 方法。但是在我的应用程序中,我知道我所有的课程。那么,使用这种方法的实际目的是什么?

【问题讨论】:

  • 这个问题很有用

标签: java oop


【解决方案1】:

但是在我的应用程序中,我知道我的所有课程。那么,使用这种方法的实际目的是什么?

那么写到这里,你还知道things[0]真正的类是什么吗?

Object[] things = new Object[]{
        "Hi mum", new Integer(42), /* and a whole bunch more */};
shuffle(things);

理论上,您可以使用instanceof 表达式的长系列来计算things[0] 的类,但这很痛苦。这样就解决了问题。

Class cls = things[0].getClass();

现在,我承认你并不经常需要做这种事情。但是当你这样做时,Object.getClass() 的功能几乎是不可或缺的。

正如其他答案所指出的,getClass() 方法对于利用反射来绕过静态类型限制的应用程序非常重要。


我猜,另一个问题是Object.getClass()方法的存在是否对JVM性能有影响。答案是否定的。该方法只是公开为了实现instanceof 运算符而必须存在的信息。这些信息通常被垃圾收集器使用。

【讨论】:

  • 嘿,看,他回答了关于生命宇宙和一切的问题和答案!
  • 我猜 medopal 只是喜欢你提到 42;我不认为这是消极的意思。哦,还有 +1,顺便说一句(不是 42,而是一个好的答案)。
  • @medopal - 我很抱歉......我有时在一天结束时有点“慢”
【解决方案2】:

您正在涉足Reflection 的精彩世界。使用反射,您可以以编程方式检查类、设置它们的字段、调用它们的方法等。您可以用它做一些非常强大的东西,并且您每天使用的大多数框架(例如 Hibernate、Spring、Guice 等)非常依赖它来使事情发生。

【讨论】:

  • 很好的概述。但我认为重要的是,虽然 frameworks 可以用它做一些很棒的事情,但经典的业务代码通常应该避免(至少直接)使用它,因为它可以轻松地 让你的代码结构变得一团糟。
  • getClass 通常用于业务代码中重写equals方法时,检查另一个对象的类是否与该对象的类相同。
【解决方案3】:

getClass() 是 Object 上的公共方法,因此它被 all 类的所有实例继承。如果您正在处理某种超类型(超类或接口等)并且您想知道实现类,getClass() 会告诉您任何对象的类。然后,您可以检查课程以了解更多信息。

一个简单的例子:

public static void doSomething(Object obj) {
    if (obj.getClass().isArray()) {
        System.out.println("It's an array");
    } else {
        System.out.println("It's not an array");
    }
}

顺便说一句,getClass() 本身不是反射的一部分——它是一个简单的方法,它返回一个简单的(类)对象。但是,从getClass() 返回的类对象可以与反射一起使用(参见java.lang.reflect 包),以找出有关该类的许多有趣的事情。

【讨论】:

  • “什么都没有”,只是它返回的类型大约是任何反射代码中的 中心类型。
  • @Joachim Sauer 好的 - 你是对的。那有点过头了。我已经修改了我的帖子:)
【解决方案4】:

有时我们需要一个对象的Class 实例。就像我们针对接口编程,但现在需要实现的实际类型:

List<?> someListImplementation = geListMagically();
System.out.println(someListImplementation.getClass().getName());

这是为什么我们需要 getClass() on java.lang.Object 的简单示例:

Object obj = "A String";
System.out.println(obj.getClass().getName()); // calls Object#getClass()
                                              // and prints java.lang.String :)

【讨论】:

    【解决方案5】:

    您可以使用Class 对象进行反射,或者您可以将它们用于其他事情,例如将有关事物的数据保存在类级别的映射中的键。

    例如,您可能有一个具有静态和方法的类,这些类可以执行实例化对象和收集统计信息等操作。事实上,你可能有几个这样的类,它们都做同样的事情,而且似乎都以同样的方式运行,因此有收敛的可能性。由于类是静态的,因此您自然会获得从类到某些状态的映射以及对该状态的操作。

    因此,您可以从静态类中提取公共代码并将它们放入提供所有方法的类中,并添加Class 参数来指定在后续操作期间应使用的状态。

    但在我的应用程序中,我知道我的所有课程。那么,使用这种方法的实际目的是什么?

    现在您已经有了一个在 Class 对象上运行的系统,您可以为其提供您不拥有的对象,例如您决定在应用程序中使用的第三方库,您可以这样做它在运行时!

    【讨论】:

      【解决方案6】:

      JavaDoc 声明:

      返回的Class对象是被表示类的static synchronized方法锁定的对象。

      这意味着,如果你的类有一个static synchronized 方法,JVM 使用getClass() 来锁定该方法。

      【讨论】:

      • 这里没有证据表明 JVM 确实为此目的调用了 getClass()。这似乎是可能的,但 Javadoc 并未暗示。
      • @EJB - 引用的 javadoc 文本是 明确的非分类声明,这就是 JVM 所做的。引文中使用的语言没有为“也许/也许不是”留下空间。
      【解决方案7】:

      您可以使用:

      • 获取类的构造函数:
       Constructor[] constructors = this.getClass().getConstructors()
      
      • 获取类的字段(反射):
         Field[] fields = this.getClass().getFields();
      
      • 在 equals 方法中使用它而不是 instanceof 来保持 equal 方法的对称契约(如 here 所述)
      if (obj == null)
        return false;
      if (getClass() != obj.getClass())
        return false;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-25
        • 1970-01-01
        相关资源
        最近更新 更多