85

假设我有一个名为Entity. 在那个类中,我有一个静态方法来检索类名:

class Entity {
    public static String getClass() {
        return Entity.class.getClass();
    }
}

现在我有另一个类扩展它。

class User extends Entity {
}

我想获取用户的类名:

System.out.println(User.getClass());

我的目标是看到控制台的“com.packagename.User”输出,但我最终会得到“com.packagename.Entity”,因为实体类是直接从静态方法引用的。

如果这不是静态方法,则可以通过this在类中使用关键字Entity(即:)轻松解决return this.class.getClass()。但是,我需要这种方法保持静态。关于如何解决这个问题的任何建议?

4

12 回答 12

102

Don't make the method static. The issue is that when you invoke getClass() you are calling the method in the super class - static methods are not inherited. In addition, you are basically name-shadowing Object.getClass(), which is confusing.

If you need to log the classname within the superclass, use

return this.getClass().getName();

This will return "Entity" when you have an Entity instance, "User" when you have a User instance, etc.

于 2010-08-05T18:36:54.423 回答
42

Not possible. Static methods are not runtime polymorphic in any way. It's absolutely impossible to distinguish these cases:

System.out.println(Entity.getClass());
System.out.println(User.getClass());

They compile to the same byte code (assuming that the method is defined in Entity).

Besides, how would you call this method in a way where it would make sense for it to be polymorphic?

于 2010-08-05T18:37:47.007 回答
8

这对我有用

this.getClass().asSubclass(this.getClass())

但我不确定它是如何工作的。

于 2017-08-01T08:54:53.173 回答
6

您的问题含糊不清,但据我所知,您想从静态方法中了解当前类。类相互继承这一事实是无关紧要的,但为了便于讨论,我也以这种方式实现了它。

类父{
    公共静态无效打印类(){
      System.out.println(Thread.currentThread().getStackTrace()[2].getClassName());
    }
}

公共类测试扩展父{
    公共静态无效主要(字符串[]参数){
      打印类();
    }
}
于 2010-08-05T18:44:43.593 回答
3

超类甚至不应该知道子类的存在,更不用说基于子类的完全限定名执行操作了。如果您确实需要基于确切类的操作,并且无法通过继承执行必要的功能,您应该按照以下方式进行操作:

public class MyClassUtil
{
    public static String doWorkBasedOnClass(Class<?> clazz)
    {
        if(clazz == MyNormalClass.class)
        {
            // Stuff with MyNormalClass
            // Will not work for subclasses of MyNormalClass
        }

        if(isSubclassOf(clazz, MyNormalSuperclass.class))
        {
            // Stuff with MyNormalSuperclass or any subclasses
        }

        // Similar code for interface implementations
    }

    private static boolean isSubclassOf(Class<?> subclass, Class<?> superclass)
    {
        if(subclass == superclass || superclass == Object.class) return true;

        while(subclass != superclass && subclass != Object.class)
        {
            subclass = subclass.getSuperclass();
        }
        return false;
    }
}

(未经测试的代码)

这个类也不知道它自己的子类,而是使用这个Class类来执行操作。最有可能的是,它仍然会与实现紧密相连(通常是一件坏事,或者如果不是坏事也不是特别),但我认为这样的结构比一个超类弄清楚它的所有子类是什么要好。

于 2010-08-05T18:56:34.070 回答
2

为什么要实现自己的 getClass() 方法?你可以使用

System.out.println(User.class);

编辑(详细说明):您希望该方法是静态的。在这种情况下,您必须在您想要其类名的类上调用该方法,无论是子类还是超类。然后MyClass.getClass(),您可以直接调用MyClass.classor ,而不是调用MyClass.class.getName()

此外,您正在创建一个与实例方法static具有相同签名的Object.getClass()方法,该方法不会编译。

于 2010-08-05T18:29:47.973 回答
2
  1. 在超类中创建成员 String 变量。
  2. 将 this.getClass().getName() 添加到将值存储在成员 String 变量中的构造函数中。
  3. 创建一个 getter 以返回名称。

每次实例化扩展类时,其名称都将存储在 String 中,并可通过 getter 访问。

于 2013-09-11T21:37:03.663 回答
0

如果我做对了,您想在静态方法的基类中使用您的子类,我认为您可以通过将类参数传递给方法来做到这一点

class Entity {
    public static void useClass(Class c) {
        System.out.println(c);
        // to do code here
    }
}

class User extends Entity {
}

class main{
    public static void main(String[] args){
        Entity.useClass(Entity.class);
    }
}
于 2014-12-18T06:02:33.283 回答
0

A static method is associated with a class, not with a specific object.

Consider how this would work if there were multiple subclasses -- e.g., Administrator is also an Entity. How would your static Entity method, associated only with the Entity class, know which subclass you wanted?

You could:

  • Use the existing getClass() method.
  • Pass an argument to your static getClass() method, and call an instance method on that object.
  • Make your method non-static, and rename it.
于 2010-08-05T18:38:00.767 回答
0

If I understand your question correctly, I think the only way you can achieve what you want is to re-implement the static method in each subclass, for example:

class Entity {
    public static String getMyClass() {
        return Entity.class.getName();
    }
}

class Derived extends Entity {
    public static String getMyClass() {
        return Derived.class.getName();
    }
}

This will print package.Entity and package.Derived as you require. Messy but hey, if those are your constraints...

于 2010-08-05T18:40:33.520 回答
0

我的上下文:具有 XML 对象子类的超类实体。我的解决方案:在超类中创建一个类变量

Class<?> claz;

然后在子类中我会在构造函数中设置超类的变量

public class SubClass {
   public SubClass() {
     claz = this.getClass();
   }
}
于 2016-07-26T10:19:54.147 回答
-4

这很简单

User.getClass().getSuperclass()

于 2012-10-10T00:11:25.370 回答