Как вы получаете доступ к защищенному методу Java в библиотеке третьих сторон? - PullRequest
7 голосов
/ 20 июня 2011

Предположим, что вы должны получить доступ к защищенному методу объекта Java, который вы получаете где-то в вашем коде.Каково ваше решение?

Я знаю один подход: вы можете использовать рефлексию и вызвать setAccessible (true) для объекта Method.

Есть еще идеи?

Ответы [ 7 ]

5 голосов
/ 20 июня 2011

Согласно модификаторам java-доступа , помимо расширения объекта (что невозможно, если вы получаете объект), есть доступ к нему из объекта в том же пакете, что и полученный вами объект.Таким образом, вы можете создать класс-оболочку в том же пакете , который извлекает атрибут через защищенный для вас метод.

5 голосов
/ 20 июня 2011

Вы можете создать подкласс метода, создать открытый метод, который вызывает защищенный метод и возвращает результат.

Если вы не можете этого сделать (если класс является окончательным), тогда setAccessible - ваш единственный способ.

4 голосов
/ 20 июня 2011

Вы также можете расширить класс, переопределить метод и сделать переопределенный метод общедоступным.Затем просто вызовите super.method ().

4 голосов
/ 20 июня 2011

Еще один вариант - создать класс, который расширяет класс третьей стороны, в котором есть интересующий вас защищенный метод.

public class ThirdPartyClass
{
   protected void foo(){}
}

и

public MyClass extends ThirdPartyClass
{

     public void callFoo()
     {
           foo();
     }

}
3 голосов
/ 20 июня 2011

Другой способ - расширить класс (если это возможно) и получить доступ к защищенному методу с помощью наследования. Если вы не создадите Объект, это невозможно, так как вам это понадобится во время компиляции, и вам нужно будет создать Объект самостоятельно.

Изворотливое решение может заключаться в использовании композиции. Таким образом, вы создаете класс в том же пакете, например OtherObjectWrapper. Поскольку он находится в том же пакете, вы можете вызывать защищенный метод объекта через открытый API, который вы предоставляете. Это не рекомендуется, так как вам не принадлежит пакет, к которому вы добавляете класс, и вы можете сделать свой код очень хрупким, например

package com.foo;

public class OtherObjectWrapper {
   private com.foo.OtherObject wrappedObject;

   public OtherObjectWrapper(com.foo.OtherObject wrappedObject) {
     this.wrappedObject = wrappedObject;
   }

   public void callTheProtectedMethod() {
     wrappedObject.callTheProtectedMethod();
   }
}

Подумайте, что думал дизайнер API, когда они помечали метод как защищенный? Может быть, они понятия не имели, что они делают, и это должно быть публично, или, что еще хуже, это должен быть пакет приватный или приватный. Или, возможно, они сделали, и они определили, что только код в том же пакете или через наследование должен иметь доступ к защищенному методу. Если он защищен, это может быть по какой-то причине, поэтому будьте осторожны, так как вы можете связать поведение вашего кода с поведением, которое может изменить и нарушить ваш код. Также посмотрите, кто владеет сторонним объектом и существует ли лучший API для доступа к функциональности защищенного метода.

2 голосов
/ 20 июня 2011

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

1 голос
/ 20 июня 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...