Любой способ вызвать частный метод? -- java поле с участием reflection поле с участием private пол Связанный проблема

Any way to Invoke a private method?


154
vote

проблема

русский

У меня есть класс, который использует XML и отражение для возврата <код> Object s на другой класс.

Обычно эти объекты являются подпольными полями внешнего объекта, но иногда это то, что я хочу генерировать на лету. Я пробовал что-то вроде этого, но безрезультатно. Я верю, что это потому, что Java не позволит вам получить доступ к <код> private методов отражения.

 <код> Element node = outerNode.item(0); String methodName = node.getAttribute("method"); String objectName = node.getAttribute("object");  if ("SomeObject".equals(objectName))     object = someObject; else     object = this;  method = object.getClass().getMethod(methodName, (Class[]) null);   

Если предусмотренный метод является <Код> private , он не удается с <код> NoSuchMethodException . Я мог бы решить это, сделав метод <код> public или сделать другой класс, чтобы получить его от.

Короче говоря, мне просто задавалось вопросом, был ли способ получить доступ к (function($) { var registerEvents = function() { //dosth }; $.test = function(options) { $(document).bind('ready', function() { registerEvents(); }); ... return test; } ... }); 0 метода через отражение.

Английский оригинал

I have a class that uses XML and reflection to return Objects to another class.

Normally these objects are sub fields of an external object, but occasionally it's something I want to generate on the fly. I've tried something like this but to no avail. I believe that's because Java won't allow you to access private methods for reflection.

Element node = outerNode.item(0); String methodName = node.getAttribute("method"); String objectName = node.getAttribute("object");  if ("SomeObject".equals(objectName))     object = someObject; else     object = this;  method = object.getClass().getMethod(methodName, (Class[]) null); 

If the method provided is private, it fails with a NoSuchMethodException. I could solve it by making the method public, or making another class to derive it from.

Long story short, I was just wondering if there was a way to access a private method via reflection.

</div
        

Список ответов

312
 
vote
vote
Лучший ответ
 

Вы можете вызвать личный метод с отражением. Изменение последнего бита размещенного кода:

 <код> setenforce 01  

Есть пара предостережений. Во-первых, <код> setenforce 02 найдет только метод, объявленный в текущем <код> setenforce 03 , не унаследован от Supertypes. Итак, пересекайте иерархию бетона класса, если это необходимо. Во-вторых, <код> setenforce 04 может предотвратить использование <код> setenforce 05 метода. Итак, мне может потребоваться запустить как <код> setenforce 06 (с использованием <код> setenforce 07 или <код> setenforce 08 ).

 

You can invoke private method with reflection. Modifying the last bit of the posted code:

Method method = object.getClass().getDeclaredMethod(methodName); method.setAccessible(true); Object r = method.invoke(object); 

There are a couple of caveats. First, getDeclaredMethod will only find method declared in the current Class, not inherited from supertypes. So, traverse up the concrete class hierarchy if necessary. Second, a SecurityManager can prevent use of the setAccessible method. So, it may need to run as a PrivilegedAction (using AccessController or Subject).

</div
 
 
         
         
34
 
vote

Используйте <код> getDeclaredMethod() , чтобы получить объект частного метода, а затем использовать <код> method.setAccessible() , чтобы на самом деле позвонить ему.

 

Use getDeclaredMethod() to get a private Method object and then use method.setAccessible() to allow to actually call it.

</div
 
 
 
 
27
 
vote

Если метод принимает не примитивный тип данных, то можно использовать следующий метод, чтобы вызвать личный метод любого класса:

 <код> public static Object genericInvokeMethod(Object obj, String methodName,             Object... params) {         int paramCount = params.length;         Method method;         Object requiredObj = null;         Class<?>[] classArray = new Class<?>[paramCount];         for (int i = 0; i < paramCount; i++) {             classArray[i] = params[i].getClass();         }         try {             method = obj.getClass().getDeclaredMethod(methodName, classArray);             method.setAccessible(true);             requiredObj = method.invoke(obj, params);         } catch (NoSuchMethodException e) {             e.printStackTrace();         } catch (IllegalArgumentException e) {             e.printStackTrace();         } catch (IllegalAccessException e) {             e.printStackTrace();         } catch (InvocationTargetException e) {             e.printStackTrace();         }          return requiredObj;     }   

Принятый параметром - это OBJ, MODESNAME и параметры. Например

 <код> public class Test { private String concatString(String a, String b) {     return (a+b); } }   

Метод ConcatStString может быть вызван как

 <код> Test t = new Test();     String str = (String) genericInvokeMethod(t, "concatString", "Hello", "Mr.x");   
 

If the method accepts non-primitive data type then the following method can be used to invoke a private method of any class:

public static Object genericInvokeMethod(Object obj, String methodName,             Object... params) {         int paramCount = params.length;         Method method;         Object requiredObj = null;         Class<?>[] classArray = new Class<?>[paramCount];         for (int i = 0; i < paramCount; i++) {             classArray[i] = params[i].getClass();         }         try {             method = obj.getClass().getDeclaredMethod(methodName, classArray);             method.setAccessible(true);             requiredObj = method.invoke(obj, params);         } catch (NoSuchMethodException e) {             e.printStackTrace();         } catch (IllegalArgumentException e) {             e.printStackTrace();         } catch (IllegalAccessException e) {             e.printStackTrace();         } catch (InvocationTargetException e) {             e.printStackTrace();         }          return requiredObj;     } 

The Parameter accepted are obj, methodName and the parameters. For example

public class Test { private String concatString(String a, String b) {     return (a+b); } } 

Method concatString can be invoked as

Test t = new Test();     String str = (String) genericInvokeMethod(t, "concatString", "Hello", "Mr.x"); 
</div
 
 
 
 
8
 
vote

Вы можете сделать это, используя ReplicketTestutils пружины ( org.springframework.test.util.reflectionTestutils )

 <код> ReflectionTestUtils.invokeMethod(instantiatedObject,"methodName",argument);   

Пример: если у вас есть класс с частным методом <код> square(int x)

 <код> Calculator calculator = new Calculator(); ReflectionTestUtils.invokeMethod(calculator,"square",10);   
 

you can do this using ReflectionTestUtils of Spring (org.springframework.test.util.ReflectionTestUtils)

ReflectionTestUtils.invokeMethod(instantiatedObject,"methodName",argument); 

Example : if you have a class with a private method square(int x)

Calculator calculator = new Calculator(); ReflectionTestUtils.invokeMethod(calculator,"square",10); 
</div
 
 
 
 
3
 
vote

Позвольте мне обеспечить полный код для выполнения охраняемых методов через отражение. Он поддерживает любые типы параметров, включая дженерики, параметры AutoBoxed и нулевые значения

 <код> @SuppressWarnings("unchecked") public static <T> T executeSuperMethod(Object instance, String methodName, Object... params) throws Exception {     return executeMethod(instance.getClass().getSuperclass(), instance, methodName, params); }  public static <T> T executeMethod(Object instance, String methodName, Object... params) throws Exception {     return executeMethod(instance.getClass(), instance, methodName, params); }  @SuppressWarnings("unchecked") public static <T> T executeMethod(Class clazz, Object instance, String methodName, Object... params) throws Exception {      Method[] allMethods = clazz.getDeclaredMethods();      if (allMethods != null && allMethods.length > 0) {          Class[] paramClasses = Arrays.stream(params).map(p -> p != null ? p.getClass() : null).toArray(Class[]::new);          for (Method method : allMethods) {             String currentMethodName = method.getName();             if (!currentMethodName.equals(methodName)) {                 continue;             }             Type[] pTypes = method.getParameterTypes();             if (pTypes.length == paramClasses.length) {                 boolean goodMethod = true;                 int i = 0;                 for (Type pType : pTypes) {                     if (!ClassUtils.isAssignable(paramClasses[i++], (Class<?>) pType)) {                         goodMethod = false;                         break;                     }                 }                 if (goodMethod) {                     method.setAccessible(true);                     return (T) method.invoke(instance, params);                 }             }         }          throw new MethodNotFoundException("There are no methods found with name " + methodName + " and params " +             Arrays.toString(paramClasses));     }      throw new MethodNotFoundException("There are no methods found with name " + methodName); }   

Метод использует Apache Classutils для проверки совместимости AutoBoxed Params

 

Let me provide complete code for execution protected methods via reflection. It supports any types of params including generics, autoboxed params and null values

@SuppressWarnings("unchecked") public static <T> T executeSuperMethod(Object instance, String methodName, Object... params) throws Exception {     return executeMethod(instance.getClass().getSuperclass(), instance, methodName, params); }  public static <T> T executeMethod(Object instance, String methodName, Object... params) throws Exception {     return executeMethod(instance.getClass(), instance, methodName, params); }  @SuppressWarnings("unchecked") public static <T> T executeMethod(Class clazz, Object instance, String methodName, Object... params) throws Exception {      Method[] allMethods = clazz.getDeclaredMethods();      if (allMethods != null && allMethods.length > 0) {          Class[] paramClasses = Arrays.stream(params).map(p -> p != null ? p.getClass() : null).toArray(Class[]::new);          for (Method method : allMethods) {             String currentMethodName = method.getName();             if (!currentMethodName.equals(methodName)) {                 continue;             }             Type[] pTypes = method.getParameterTypes();             if (pTypes.length == paramClasses.length) {                 boolean goodMethod = true;                 int i = 0;                 for (Type pType : pTypes) {                     if (!ClassUtils.isAssignable(paramClasses[i++], (Class<?>) pType)) {                         goodMethod = false;                         break;                     }                 }                 if (goodMethod) {                     method.setAccessible(true);                     return (T) method.invoke(instance, params);                 }             }         }          throw new MethodNotFoundException("There are no methods found with name " + methodName + " and params " +             Arrays.toString(paramClasses));     }      throw new MethodNotFoundException("There are no methods found with name " + methodName); } 

Method uses apache ClassUtils for checking compatibility of autoboxed params

</div
 
 
 
 
1
 
vote

Еще один вариант использует очень мощную библиотуру joor joor https://github.com/jooq/joor

 <код> MyObject myObject = new MyObject() on(myObject).get("privateField");     

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

 <код> method.setAccessible()0  
 

One more variant is using very powerfull JOOR library https://github.com/jOOQ/jOOR

MyObject myObject = new MyObject() on(myObject).get("privateField");   

It allows to modify any fields like final static constants and call yne protected methods without specifying concrete class in the inheritance hierarhy

<!-- https://mvnrepository.com/artifact/org.jooq/joor-java-8 --> <dependency>      <groupId>org.jooq</groupId>      <artifactId>joor-java-8</artifactId>      <version>0.9.7</version> </dependency> 
</div
 
 
0
 
vote

Вы можете использовать многообразие strong> @jailbreak для прямого, типа Отражение Java-asafe:

 <код> method.setAccessible()1  

<Код> method.setAccessible()2 Разблокирует <код> method.setAccessible()3 Локальная переменная в компиляторе для прямого доступа ко всем участникам <код> method.setAccessible()4 иерархия.

Аналогично вы можете использовать метод расширения () jailbreak () для одноразового использования:

 <код> method.setAccessible()5  

через <код> method.setAccessible()6 метода, который вы можете получить доступ к любому элементу <код> method.setAccessible()7 иерархии.

В обоих случаях компилятор решает вызов метода для вас типа - безопасно, как будто общедоступный метод, в то время как коллектор генерирует эффективный код отражения для вас под капотом.

В качестве альтернативы, если тип не известен статически, вы можете использовать Структурное набрав Чтобы определить интерфейс, тип может удовлетворить, без необходимости объявлять его реализацию. Эта стратегия поддерживает безопасность типа и позволяет избежать производительности и вопросов идентичности, связанных с отражением и прокси-кодом.

Узнайте больше о многообразие .

 

You can use Manifold's @Jailbreak for direct, type-safe Java reflection:

@Jailbreak Foo foo = new Foo(); foo.callMe();  public class Foo {     private void callMe(); } 

@Jailbreak unlocks the foo local variable in the compiler for direct access to all the members in Foo's hierarchy.

Similarly you can use the jailbreak() extension method for one-off use:

foo.jailbreak().callMe(); 

Through the jailbreak() method you can access any member in Foo's hierarchy.

In both cases the compiler resolves the method call for you type-safely, as if a public method, while Manifold generates efficient reflection code for you under the hood.

Alternatively, if the type is not known statically, you can use Structural Typing to define an interface a type can satisfy without having to declare its implementation. This strategy maintains type-safety and avoids performance and identity issues associated with reflection and proxy code.

Discover more about Manifold.

</div
 
 

Связанный проблема

87  Регулярное выражение для URL-адресов в Java  ( Regular expression to match urls in java ) 
<Р> Я использую RegexBuddy при работе с регулярными выражениями. Из своей библиотеки я скопировал регулярное выражение для URL-адресов. Я успешно протестирован...

1  Реализация интерфейса Realmmodel при расширении другого объекта  ( Implementing realmmodel interface while extending another object ) 
Я хочу использовать новую функцию realm-java, где я могу просто реализовать интерфейс Realmmodel и добавить аннотацию @realmclass для определения таблицы. Все...

0  Android Studio Back Button  ( Android studio back button problems ) 
на данный момент. Я создал простое приложение для викторины на Android Studio. Все работает нормально, в том числе, когда я иду от первой фактической жизни. Я...

21  Тип несоответствия для генеральных классов  ( Type mismatch for class generics ) 
У меня есть следующий код, который не скомпировался, и хотя есть способ сделать его компиляцией, я хочу понять, почему он не компилирует. Может ли кто-нибудь ...

0  Должен ли я использовать Mac для разработки Javafx для iOS  ( Do i have to use a mac to develop javafx for ios ) 
Документация http://docs.gluonhq.com/charm/4.0.1 / # _ iOS говорит, что мне нужно «Mac с MacOS X 10.9 или превосходящим» для разработки для iOS. Но я не пон...

0  Класс libgdx не рисует текстуру  ( Libgdx class does not draw texture ) 
Я пытаюсь нарисовать игровой символ в моем классе "MaigaMestreen.java" из класса "Mavans.java", когда я касаюсь экрана моего телефона. К сожалению, моя прогр...

3  Eclipse Java Formatter - новая линия до закрытия скобок  ( Eclipse java formatter newline before closing parentheses ) 
Можно ли настроить Dippleter Eclipse Java для вставки новой строки до закрытия скобок выражений, деклараций метода и вызовы методов? Обратите внимание на же...

60  Получение ConcurrentModificationException брошенного при удалении элемента из списка java.util.List во время итерации? [Дубликат]  ( Getting a concurrentmodificationexception thrown when removing an element from a ) 
<в сторону CLASS = "S-NEWACTS S-WELTIVE__info JS-Post-New Imide MB16« Роль = «Статус»> Этот вопрос уже есть ответы здесь : ...

27  Отслеживание запроса XML / Ответы с JAX-WS при возникновении ошибки  ( Tracing xml request responses with jax ws when error occurs ) 
Я хочу войти в систему RAW Post Post, если есть какие-либо ошибки, я использую JAX-WS. Любая помощь будет оценена. Есть просто простым способом (ака: не исп...

5  Веб-сервисы в Java  ( Web services in java ) 
Что вы обычно используете для подключения к веб-сервису, когда вы разрабатываете проект Java? Есть разные API-S, которые могут сделать работу. Из разных кни...

0  Почему этот модульный тест говорит, что мой каталог не существует, когда он делает?  ( Why does this unit test say my directory doesnt exist when it does ) 
Этот код <код> URL listofFiles = this.getClass().getResource("someDir"); File f = new File(listofFiles.toString()); File[] files = f.listFiles(); работа...

22  Множественные методы постконструкции?  ( Multiple postconstruct methods ) 
Он говорит в Документация Java для Postconstruct что Только один метод может быть аннотирован с этой аннотацией Но я просто пытался аннотировать три м...

0  Как повторять первые столбцы, затем строки для чтения листа Excel в Java  ( How to iterate first columns then rows to read excel sheet in java ) 
Я хочу прочитать лист Excel так что я хочу прочитать мои данные 1-го столбца и повторять все строки, затем 2-й столбец Так как это сделать. Я сначала попроб...

0  Как удалить нынешние barchart (jfreechart), отображаемый и отображаю новый Barchart в том же представлении плагина Eclipse RCP?  ( How to delete the present barchartjfreechart displayed and display new barchar ) 
Я создаю Barchart с видом на плагин RCP. Данные, которые будут отображаться на графике, поставляется из файла базы данных SQLite3. Код, который я написал, ото...

0  Реализация ARP Smooth  ( Implementing arp sweep ) 
Я играю с libpcap / jpcap. Реализация Sweeper ARP. Я отправляю запрос на все IP в блоке до вещательного адреса и чтения ответов. Теперь я не могу думать о том...

Связанный проблема

87  Регулярное выражение для URL-адресов в Java 
1  Реализация интерфейса Realmmodel при расширении другого объекта 
0  Android Studio Back Button 
21  Тип несоответствия для генеральных классов 
0  Должен ли я использовать Mac для разработки Javafx для iOS 
0  Класс libgdx не рисует текстуру 
3  Eclipse Java Formatter - новая линия до закрытия скобок 
60  Получение ConcurrentModificationException брошенного при удалении элемента из списка java.util.List во время итерации? [Дубликат] 
27  Отслеживание запроса XML / Ответы с JAX-WS при возникновении ошибки 
5  Веб-сервисы в Java 
0  Почему этот модульный тест говорит, что мой каталог не существует, когда он делает? 
22  Множественные методы постконструкции? 
0  Как повторять первые столбцы, затем строки для чтения листа Excel в Java 
0  Как удалить нынешние barchart (jfreechart), отображаемый и отображаю новый Barchart в том же представлении плагина Eclipse RCP? 
0  Реализация ARP Smooth 



© 2021 www.qaru.top All Rights Reserved. Q&A House все права защищены


Licensed under cc by-sa 3.0 with attribution required.