2009-10-02 2 views
2

Рассмотрим этот код JavaJava, получить объект класса для размещения класса, не выполнения Класс

class A{ 
//@returns Class object this method is contained in 
// should be A in this case 
public Class<?> f() { 
    return getClass(); 
} 
} 

class B extends A {} 

B b = new B(); 

System.out.println(b.f()); 
//output -- B.class (Wrong, should be A.class) 

внутри f() я не могу использовать getClass() потому, что даст мне runtype, который B. Я ищу способ, чтобы получить Class объект classf() находится внутри (не упоминая A явно, очевидно)

+4

Почему вы не хотите упоминать Я явно? 'A.class' кажется самым простым решением. –

+0

Я думаю, что если вам нужно выяснить, какой именно тип вашего экземпляра во время выполнения, дает сильный сигнал о том, что необходимо выполнить некоторые рефакторинг или переосмысление. – aberrant80

ответ

4

Вы можете использовать стек исключений трассировки, чтобы сделать что-то вроде этого:

public String f() { 
    Exception E = new Exception(); 
    E.fillInStackTrace(); 
    return E.getStackTrace()[0].getClassName(); // load it if you need to return class 
} 
+0

приятно, это действительно умно – Mike

+4

Вам не нужно исключение, чтобы получить stacktrace. Это намного лучший способ: Thread.currentThread(). GetStackTrace(). –

+3

Собственно, это не работает. Thread.currentThread(). GetStackTrace() заполняет трассировку стека собственными методами Thread - самой dumpThreads() и getStackTrace(), хотя она, возможно, отличается в зависимости от версии/реализации JVM. – ChssPly76

1

Вы можете использовать

class.getMethod("f",parameterTypes).getDeclaringClass() 
+0

Это будет работать только для общедоступных методов; плюс это довольно грязное дело с параметрами. – ChssPly76

+0

Вы оба правы. Подход с использованием трассировки стека, вероятно, лучше. И, конечно, это должно быть getClass (исправлено). f не обязательно должно быть окончательным. Зачем это нужно? – sleske

2

Я бы сказал, что было бы намного проще и понятнее просто вернуть A.class в качестве предлагаемого @mmyers. Нет смысла пытаться получить его во время выполнения, если вы действительно не хотите значения времени выполнения. Единственная проблема, которая возникает, - это рефакторинг имени класса, а другой с тем же именем существует, в том же пакете.

Я бы выбрал этот шанс для ясности в коде.

+0

Точно. Ответы на производные слишком усложняют ситуацию. – aberrant80

6

new Object() {}.getClass().getEnclosingClass(). Но, пожалуйста, не надо!

+0

Теперь это кливер! – Yishai

+0

Да, я узнал это от кого-то еще. –

1

Я знаю, что ты сказал, что не хотел бы упомянуть A.class явно

class A {   
    public Class<?> f() { 
     return A.class; 
    } 
} 

, но я изо всех сил, чтобы найти случай, когда использование приведенный выше код не является удовлетворительным.

Смежные вопросы