Как получить имя вызывающего classа в Java?

Я хотел бы помочь в этом вопросе,

Пример:

public class A { private void foo() { //Who Invoked me } } public class B extends A { } public class C extends A { } public class D { C.foo(); } 

Это в основном сценарий. Мой вопрос в том, как метод foo() знает, кто его называет?

EDIT : В основном я пытаюсь сделать слой базы данных, а в classе AI создаст метод, который будет генерировать SQL-запросы. Такие операторы динамически генерируются путем получения значений всех общедоступных свойств вызывающего classа.

Самый простой способ заключается в следующем:

 String className = new Exception().getStackTrace()[1].getClassName(); 

Но в реале не должно быть необходимости в этом, если только для некоторых целей ведения журнала, потому что это довольно дорогостоящая задача. Что это, проблема, для которой вы думаете, что это решение? Мы можем придумать -лучшие предложения.

Изменить : вы прокомментировали следующее:

в основном я пытаюсь выполнить Layer базы данных, и в classе A я создам метод, который будет генерировать SQL-выражения, такие операторы динамически генерируются путем получения значений всех общедоступных свойств вызывающего classа.

Затем я настоятельно рекомендую искать существующую библиотеку ORM , такую ​​как Hibernate , iBatis или любую реализацию JPA на ваш вкус.

Возможно, для вашего случая использования было бы целесообразно передать class вызывающего в метод, например:

 public class A { public void foo(Class c) { ... } } 

И назовите это примерно так:

 public class B { new A().foo(getClass() /* or: B.class */ ); } 

Java 9: ​​API Walking Walking

JEP 259 обеспечивает эффективный стандартный API для стековой ходьбы, который позволяет легко фильтровать и ленивый доступ к информации в трассировке стека. Прежде всего, вы должны получить экземпляр StackWalker :

 import static java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE; // other imports StackWalker walker = StackWalker.getInstance(RETAIN_CLASS_REFERENCE); 

Вы можете вызвать метод getCallerClass() :

 Class callerClass = walker.getCallerClass(); 

Независимо от того, как вы настроили экземпляр getCallerClass метод getCallerClass будет игнорировать кадры отражения, скрытые кадры и связанные с MethodHandle s. Кроме того, этот метод не следует вызывать в первом стеке стека.

foo () является закрытым, поэтому вызывающий абонент всегда будет в classе A.

если вы используете slf4j в качестве вашей системы регистрации приложений. вы можете использовать:

 Class source = org.slf4j.helpers.Util.getCallingClass(); 

Я думаю, что это быстрее, чем новый Exception (). GetStackTrace (), поскольку getStackTrace () alaways делает clone stacktrace.

Хакерным решением является sun.reflect.Reflection.getCallerClass .

 public void foo() { Class caller = sun.reflect.Reflection.getCallerClass(); // ... } 

Это взломанно, потому что вы должны убедиться, что class, который вызывает Reflection.getCallerClass() , загружается в загрузочный class ClassLoader для annotations @CallerSensitive (с помощью которого getCallerClass помечен). Таким образом, это, вероятно, не лучшее решение для проекта, если только ваш проект не использует Java-агент для добавления ваших classов в поиск начальной загрузки ClassLoader.

Я пробовал это, и он работает хорошо. Это связано с тем, что каждый объект Java имеет доступ к методу getClass (), который возвращает вызывающего объекта classа и имя метода.

 public Logger logger() { return Logger.getLogger(getClass().toString()); } 

пример использования:

 public DBTable(String tableName) { this.tableName = tableName; loadTableField(); this.logger().info("done"); } 

образец журнала вывода с использованием java.util.logging.Logger;

Feb 01, 2017 11:14:50 PM rmg.data.model.DBTable (init) INFO: done

Может быть, ответ здесь:

 public class CallerMain { public void foo(){ System.out.println("CallerMain - foo"); System.out.println(this.getClass());//output- callerMain } public static void main(String[] args) { A a = new A(); CallerMain cm = new CallerMain(); cm.foo(); } } class A{ public void foo(){ System.out.println("A - foo"); System.out.println(this.getClass());//output- A } } 
  • Каков наиболее эффективный streamовый XSLT-процессор на основе Java?
  • Hibernate - foreign keys вместо объектов
  • Как предотвратить зависание Eclipse при запуске?
  • Библиотеки Гуавы и GWT
  • Как печатать форматированные значения BigDecimal?
  • Java JDBC игнорирует setFetchSize?
  • Когда использовать LinkedList над ArrayList?
  • альтернатива memcached, которая может сохраняться на диске
  • Различия между System.out.println () и возвратом в Java
  • Класс является сырым типом. Ссылки на общий тип Class должны быть параметризованы
  • «Нестатическая переменная, на которую нельзя ссылаться из статического контекста» при создании объекта
  • Давайте будем гением компьютера.