从超类中获取子类的名称

时间:2010-08-05 18:25:28

标签: java class subclass super superclass

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

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

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

class User extends Entity {
}

我想获得User的类名:

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

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

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

12 个答案:

答案 0 :(得分:83)

不要将方法设为静态。问题是,当您调用getClass()时,您正在调用超类中的方法 - 静态方法不会被继承。另外,你基本上是名字阴影Object.getClass(),这令人困惑。

如果需要在超类中记录类名,请使用

return this.getClass().getName();

当您拥有Entity个实例时会返回“实体”,当您拥有User个实例时会返回“用户”等。

答案 1 :(得分:39)

不可能。静态方法在任何方面都不是运行时多态的。区分这些情况绝对不可能:

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

它们编译为相同的字节代码(假设该方法在Entity中定义。)

此外,你怎么称呼这种方法,使其具有多态性?

答案 2 :(得分:6)

你的问题很模糊,但据我所知,你想从静态方法知道当前的类。类继承的事实是无关紧要的,但为了讨论起见,我也是这样实现的。

class Parent {
    public static void printClass() {
      System.out.println(Thread.currentThread().getStackTrace()[2].getClassName());
    }
}

public class Test extends Parent {
    public static void main(String[] args) {
      printClass();
    }
}

答案 3 :(得分:5)

这对我有用

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

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

答案 4 :(得分: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类来执行操作。最有可能的是,它仍然与实现紧密相关(通常是坏事,或者如果不是很糟糕,它不是特别),但我认为像这样的结构比超类确定什么更好它的所有子类都是。

答案 5 :(得分:2)

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

System.out.println(User.class);

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

此外,您正在使用与static实例方法相同的签名创建Object.getClass()方法,该方法将无法编译。

答案 6 :(得分:2)

  1. 在超类中创建成员String变量。
  2. 将this.getClass()。getName()添加到构造函数中,该构造函数将值存储在成员String变量中。
  3. 创建一个getter以返回名称。
  4. 每次实例化扩展类时,其名称将存储在String中,并可通过getter访问。

答案 7 :(得分:0)

静态方法与类关联,而不与特定对象关联。

如果有多个子类,请考虑这是如何工作的 - 例如,Administrator也是一个实体。您的静态Entity方法(仅与Entity类相关联)如何知道您想要哪个子类?

你可以:

  • 使用现有的getClass()方法。
  • 将参数传递给静态getClass()方法,并在该对象上调用实例方法。
  • 使您的方法非静态,并重命名。

答案 8 :(得分:0)

如果我理解你的问题,我认为你能达到你想要的唯一方法就是在每个子类中重新实现静态方法,例如:

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

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

这将打印package.Entity和package.Derived按需要。凌乱但嘿,如果那些是你的约束......

答案 9 :(得分: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);
    }
}

答案 10 :(得分:0)

我的上下文:带有XML对象子类的超类实体。 我的解决方案 在超类

中创建一个类变量
Class<?> claz;

然后在子类中,我将在构造函数

中设置超类的变量
public class SubClass {
   public SubClass() {
     claz = this.getClass();
   }
}

答案 11 :(得分:-4)

这很简单。

User.getClass()。getSuperclass之类()