2013-04-24 3 views
0

Мой запрос предположим, что мы имеем число классов предположим, три класса есть как это:Ловля называемый метод принадлежит к какому классу

Смотрите мой обновленный запрос. Это тот случай, о котором они просили.

class MethodContainerA { 
    public void display() { 
     System.out.println("Display from MethodContainerA"); 
    } 
} 

class MethodContainerB extends MethodContainerA { 
    public void display() { 
     System.out.println("Display from MethodContainerB"); 
    } 
} 

class MethodContainerC extends MethodContainerB { 

} 

public class MethodCallRecognization { 
    public static void main(String[] args) { 
     MethodContainerC methodContainerC = new MethodContainerC(); 
     methodContainerC.display(); 

      // I want to know here 
    } 
} 

Мой вопрос заключается в том, что после вызова я могу получить информацию display() метод вызывается из какого класса. Обратите внимание: этот вопрос не для целей отладки - он теоретический.

+5

* Зачем вам нужно знать? Это запах дизайна сам по себе. –

+0

Ну, вы получаете информацию, напечатанную на консоль, или я что-то не понимаю? Что бы вы сделали с этой информацией? – slhck

+0

Итак, вы имеете в виду в MethodContainerC.display, вы хотите, чтобы он знал, что он был вызван из MethodCallRecognization? Или что? –

ответ

2

Попробуйте это.

public class MethodCallRecognization { 
    public static void main(String[] args) { 
    MethodContainerC methodContainerC = new MethodContainerC(); 
    methodContainerC.display(); 
    // I want to know here 
    String className=getClassName(methodContainerC.getClass(), "display") ; 
    System.out.println(className); 
    } 
    public static String getClassName(Class c,String methodName){ 
     Method m[]=c.getDeclaredMethods(); 
     for(Method m1:m){ 
     if(m1.getName().equals(methodName)){ 
      return c.getName(); 
     } 
     } 
     return getClassName(c.getSuperclass(),methodName); 

    } 
} 

Если методы перегружены, вы также можете проверить с помощью типов аргументов вместо имен. но это должно дать вам идею.

Согласно комментарий здесь лучше версия getClassName

public static String getClassname(Class c, String methodName){ 
try{ 
    Method m= c.getDeclaredMethod(methodName); 
    return c.getName(); 
}catch(NoSuchMethodException nse){ 
    return getClassName(c.getSuperclass(),methodName); 
} 
} 

Если dsiplay метод принимает параметр, то

public class MethodCallRecognization { 
     public static void main(String[] args) { 
     MethodContainerC methodContainerC = new MethodContainerC(); 
     methodContainerC.display("" , "");//Suppose it takes String id and String name parameter 
     // I want to know here 
     Class[] parametertype={String.class,String.class}; 
     String className=getClassName(methodContainerC.getClass(), "display", parametertype) ; 
     System.out.println(className); 
     } 
     public static String getClassname(Class c, String methodName, Class[] parametertype){ 
     try{ 
      Method m= c.getDeclaredMethod(methodName, parametertype); 
      return c.getName(); 
     }catch(NoSuchMethodException nse){ 
      return getClassName(c.getSuperclass(),methodName, parametertype); 
     } 
     } 
    } 
+0

Вы можете (предположительно) сделать getDeclaredMethod, чтобы получить только один объект Method по имени. –

+0

@HotLicks правый .. это будет лучше peformance мудрый. Благодарю. –

+0

(Это немного грязно, чтобы настроить парм.) –

1

Вы будете звонить display() от MethodContainerC и таким образом распечатать Display from MethodContainerC.

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

Однако, если у вас нет метода display() в MethodContainerC, вы будете вызывать метод отображения MethodContainerB. Это происходит потому, что наследование следует ближайший путь: (., Который переопределяется MethodContianerC)

  • MethodContianerA имеет метод display() ...
  • который переопределяется MethodContainerB ...

Если вы вырезаете последний шаг, MethodContainerB по-прежнему переопределяет display() для всех MethodContainerC. Ближайшая реализация метода всегда будет выполняться.

+0

@if дисплей тогда не записывается в MethodContainerC. –

+0

@Nikhil - Если в MethodContainerC нет метода 'display', тогда будет выведена ближайшая реализация суперкласса' display'. –

+0

Тогда вы будете называть его ближайшим суперклассным методом, и он выведет 'Display from MethodContainerB' –

3

Ну, на самом деле, вероятно, это способ сделать это (не пробовал):

Получить класс используемого экземпляра. Получите метод getDeclaredMethod для получения метода. Уберите метод getDeclaringClass в методе.

+0

уже дал ответ с кодом перед вашим ответом :). –

+0

@Hot Licks - это то, что люди начали downvoting. Я объясняю ситуацию. –

+0

@Nikhil - Имейте в виду, что этот метод не имеет никакого отношения к тому, «вы только что вызвали» метод или нет - вам просто нужен указатель экземпляра, и нет необходимости в вызове этого указателя в любом месте всего приложения. –