Java 从超类中获取子类的名称

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3417879/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 23:08:57  来源:igfitidea点击:

Getting the name of a sub-class from within a super-class

javaclasssubclasssupersuperclass

提问by Matt Huggins

Let's say I have a base class named Entity. In that class, I have a static method to retrieve the class name:

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

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

Now I have another class extend that.

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

class User extends Entity {
}

I want to get the class name of User:

我想获取用户的类名:

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

My goal is to see "com.packagename.User" output to the console, but instead I'm going to end up with "com.packagename.Entity" since the Entity class is being referenced directly from the static method.

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

If this wasn't a static method, this could easily be solved by using the thiskeyword within the Entityclass (i.e.: return this.class.getClass()). However, I need this method to remain static. Any suggestions on how to approach this?

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

采纳答案by Michael Borgwardt

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).

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

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

此外,您将如何以一种使其成为多态的方式来调用此方法?

回答by samitgaur

Why do you want to implement your own getClass() method? You can just use

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

System.out.println(User.class);

Edit(to elaborate a bit): You want the method to be static. In that case you must call the method on the class whose class name you want, be it the sub-class or the super-class. Then instead of calling MyClass.getClass(), you can just call MyClass.classor MyClass.class.getName().

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

Also, you are creating a staticmethod with the same signature as the Object.getClass()instance method, which won't compile.

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

回答by matt b

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.

不要使方法静态。问题是,当您调用时,getClass()您正在调用超类中的方法 - 不会继承静态方法。此外,您基本上是 name-shadowing Object.getClass(),这令人困惑。

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

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

return this.getClass().getName();

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

当您有Entity实例时,这将返回“实体”,当您有实例时将返回“用户” User,等等。

回答by Andy Thomas

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?

考虑一下如果有多个子类这将如何工作——例如,管理员也是一个实体。仅与 Entity 类关联的静态 Entity 方法如何知道您想要哪个子类?

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.
  • 使用现有的 getClass() 方法。
  • 将参数传递给您的静态 getClass() 方法,并在该对象上调用实例方法。
  • 使您的方法非静态,并重命名。

回答by brabster

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...

这将根据需要打印 package.Entity 和 package.Derived。凌乱但是嘿,如果这些是你的限制......

回答by Gilead

Your question is ambiguous but as far as I can tell you want to know the current class from a static method. The fact that classes inherit from each other is irrelevant but for the sake of the discussion I implemented it this way as well.

您的问题模棱两可,但据我所知,您想通过静态方法了解当前类。类相互继承这一事实无关紧要,但为了讨论起见,我也以这种方式实现了它。

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();
    }
}

回答by Brian S

The superclass should not even know of the existence of the subclass, much less perform operations based on the fully qualified name of the subclass. If you do need operations based on what the exact class is, and can't perform the necessary function by inheritance, you should do something along these lines:

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

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;
    }
}

(Untested code)

(未经测试的代码)

This class doesn't know about its own subclasses, either, but rather uses the Classclass to perform operations. Most likely, it'll still be tightly linked with implementations (generally a bad thing, or if not bad it's not especially good), but I think a structure like this is better than a superclass figuring out what all of its subclasses are.

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

回答by NightGale

it is very simple done by

这很简单,由

User.getClass().getSuperclass()

User.getClass().getSuperclass()

回答by Dawg 'N IT

  1. Create a member String variable in the superclass.
  2. Add the this.getClass().getName() to a constructor that stores the value in the member String variable.
  3. Create a getter to return the name.
  1. 在超类中创建一个成员 String 变量。
  2. 将 this.getClass().getName() 添加到将值存储在成员 String 变量中的构造函数。
  3. 创建一个 getter 来返回名称。

Each time the extended class is instantiated, its name will be stored in the String and accessible with the getter.

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

回答by Dis Honest

If i am taking it right you want to use your sub class in base class in static method I think you can do this by passing a class parameter to the method

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

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);
    }
}