Development Tip

수퍼 클래스 내에서 하위 클래스 이름 가져 오기

yourdevel 2020. 11. 7. 10:37
반응형

수퍼 클래스 내에서 하위 클래스 이름 가져 오기


라는 기본 클래스가 있다고 가정 해 보겠습니다 Entity. 이 클래스에는 클래스 이름을 검색하는 정적 메서드가 있습니다.

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

이제 다른 클래스가 확장되었습니다.

class User extends Entity {
}

User의 클래스 이름을 얻고 싶습니다.

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

내 목표는 "com.packagename.User"출력을 콘솔에 표시하는 것이지만 Entity 클래스가 정적 메서드에서 직접 참조되기 때문에 대신 "com.packagename.Entity"로 끝날 것입니다.

이것이 정적 메서드가 아니라면 클래스 this내에서 키워드 Entity(예 :)를 사용하여 쉽게 해결할 수 있습니다 return this.class.getClass(). 그러나 정적으로 유지하려면이 방법이 필요합니다. 이에 접근하는 방법에 대한 제안이 있습니까?


불가능합니다. 정적 메서드는 어떤 식 으로든 런타임 다형성이 아닙니다. 이러한 경우를 구별하는 것은 절대 불가능합니다.

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

동일한 바이트 코드로 컴파일됩니다 (메소드가에 정의되어 있다고 가정 Entity).

게다가,이 메서드를 다형성이 타당한 방식으로 어떻게 호출할까요?


메서드를 정적으로 만들지 마십시오. 문제는 호출 getClass()수퍼 클래스에서 메서드를 호출한다는 것입니다. 정적 메서드는 상속되지 않습니다. 또한 기본적으로 name-shadowing Object.getClass()이므로 혼란 스럽습니다.

수퍼 클래스 내에 클래스 이름을 기록해야하는 경우 다음을 사용하십시오.

return this.getClass().getName();

Entity인스턴스 가 있으면 "Entity"를, 인스턴스 가 있으면 "User" 를 반환 User합니다.


귀하의 질문은 모호하지만 정적 메서드에서 현재 클래스를 알고 싶다고 말할 수 있습니다. 클래스가 서로 상속한다는 사실은 관련이 없지만 토론을 위해이 방식으로 구현했습니다.

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

공용 클래스 Test extends Parent {
    public static void main (String [] args) {
      printClass ();
    }
}

이것은 나를 위해 작동합니다

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

하지만 어떻게 작동하는지 잘 모르겠습니다.


수퍼 클래스는 서브 클래스의 존재를 알지 못하며 서브 클래스의 완전한 이름을 기반으로하는 작업을 수행하는 것보다 훨씬 적습니다. 정확한 클래스에 기반한 작업이 필요하고 상속을 통해 필요한 기능을 수행 할 수없는 경우 다음과 같은 작업을 수행해야합니다.

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.


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.


  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.


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.

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


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

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

it is very simple done by

User.getClass().getSuperclass()

참고URL : https://stackoverflow.com/questions/3417879/getting-the-name-of-a-sub-class-from-within-a-super-class

반응형