从超类中获取子类的名称

发布于 2024-09-13 05:52:06 字数 601 浏览 5 评论 0原文

假设我有一个名为 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 关键字轻松解决此问题(即:return this.class.getClass( ))。但是,我需要此方法保持静态。关于如何解决这个问题有什么建议吗?

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

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.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

∝单色的世界 2024-09-20 05:52:06

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

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

return this.getClass().getName();

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

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.

﹏半生如梦愿梦如真 2024-09-20 05:52:06

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

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

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

此外,您如何以一种对多态有意义的方式调用此方法?

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?

伴我心暖 2024-09-20 05:52:06

这对我有用

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

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

This works for me

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

But I'm not sure how it works though.

你的往事 2024-09-20 05:52:06

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

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

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();
    }
}
阳光下慵懒的猫 2024-09-20 05:52:06
  1. 在超类中创建成员 String 变量。
  2. 将 this.getClass().getName() 添加到将值存储在成员 String 变量中的构造函数中。
  3. 创建一个 getter 来返回名称。

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

  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.

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

听闻余生 2024-09-20 05:52:06

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

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 类来执行操作。最有可能的是,它仍然与实现紧密相连(通常是一件坏事,或者即使不是坏事,也不是特别),但我认为这样的结构比超类更好地弄清楚什么它的所有子类都是。

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

风渺 2024-09-20 05:52:06

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

System.out.println(User.class);

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

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

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

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.class or MyClass.class.getName().

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

阪姬 2024-09-20 05:52:06

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

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

您可以:

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

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.
小耗子 2024-09-20 05:52:06

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

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 。凌乱但是嘿,如果这些是你的限制......

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

终弃我 2024-09-20 05:52:06

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

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

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);
    }
}
弱骨蛰伏 2024-09-20 05:52:06

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

Class<?> claz;

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

public class SubClass {
   public SubClass() {
     claz = this.getClass();
   }
}

My context: superclass Entity with subclasses for XML objects.
My solution:
Create a class variable in the superclass

Class<?> claz;

Then in the subclass I would set the variable of the superclass in the constructor

public class SubClass {
   public SubClass() {
     claz = this.getClass();
   }
}
是你 2024-09-20 05:52:06

完成非常简单

通过User.getClass().getSuperclass()

it is very simple done by

User.getClass().getSuperclass()

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文