Как получить доступ к экземпляру, который «владеет» методом в Java? - PullRequest
2 голосов
/ 02 апреля 2011

в java, возможно ли получить доступ к экземпляру, к которому принадлежит метод, учитывая только метод?

, например:

public class ClassA {
    private ClassB instanceB = new ClassB();
    // ...
    private void sendMethod () {
        instanceB.receiveMethod(foo);
    }
    public void foo () {}
}

public class ClassB {
    public void receiveMethod (Method method) {
        Object o = foo.getInstanceOwner();  // just made that part up...
    }
}

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

Ответы [ 4 ]

2 голосов
/ 02 апреля 2011

взято с

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

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

Вы можете вызвать Method#invoke, но вам понадобится экземпляр объекта, для которого вы хотите вызвать метод, из метода doc:

Вызывает базовый метод представленный этим объектом метода, на указанный объект с указанные параметры. Индивидуальный параметры автоматически разворачиваются чтобы соответствовать примитивным формальным параметрам, и примитив и ссылка параметры подлежат методу преобразования вызовов по мере необходимости. Если базовый метод является статическим, тогда указанный аргумент obj игнорируются. Может быть нулевым.

Если число формальных параметров требуется базовый метод 0, предоставленный массив args может иметь длина 0 или ноль.

Если основным методом является метод экземпляра, он вызывается с помощью динамический поиск метода, как описано в Спецификация языка Java, Второе издание, раздел 15.12.4.4; в в частности, переопределение на основе Тип времени выполнения целевого объекта будет происходят.

Если базовый метод является статическим, класс, который объявил метод инициализируется, если это еще не было инициализируется.

Если метод завершается нормально, Возвращаемое значение возвращается вызывающая сторона вызова; если значение имеет примитивный тип, это первый соответствующим образом завернутый в объект. Однако, если значение имеет тип массив примитивного типа, элементы массива не переносятся в объектах; другими словами, массив примитивного типа возвращается. Если базовый метод возвращает тип void, вызов возвращает ноль.

То есть TL: DR, если у вас нет фактического объекта, для которого вы хотите вызвать метод, это невозможно.

0 голосов
/ 02 апреля 2011

Вы можете сделать это, но правильным примером в вашем примере будет использование interface, потому что это, кажется, то, что вы хотите: вы хотите передать объект, с которым ClassB знает, как работать.

   interface Callback {
      void foo();
   }

   public class ClassA implements Callback {...}

   public class ClassB {
     public void receiveMethod(Callback cb) {...}
   }
0 голосов
/ 02 апреля 2011

Это все равно что спросить:

"Если яблоко от яблоневого сада, какому дереву принадлежит это яблоко?"

Ответ на этот вопрос:

"Нетидея, так как все яблони производят яблоки, они могут принадлежать любому дереву ".

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

РЕДАКТИРОВАТЬ

Из одного из ваших комментариев я понимаю, что вы ищете альтернативу шаблону Observer.Вы говорите, что вам не нравится беспорядок в шаблоне Observer, и что он не достаточно «универсален» для вас.

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

Так что, возможно, это проблема с реализацией.К счастью, я уже разместил на SO реализацию Observer в JAVA, чтобы продемонстрировать, насколько она мощна и элегантна.

Полиморфизм и интерфейсы в Java (можно ли использовать полиморфизм для реализации интерфейсов ... почему?)

На самом деле: отражение сложнее, чем при использовании интерфейса, так как вы не можете гарантировать во время компиляции, что тип объекта, который вы вызываете экземпляр метода на, даже поддерживает этот метод!(без некоторого кода проверки ошибок).В отличие от интерфейсов, такая проблема невозможна.

0 голосов
/ 02 апреля 2011
public class ClassA {
    private ClassB instanceB = new ClassB();
    // ...
    private void sendMethod () {
        Method m = ClassA.class.getMethod("foo", null);
        instanceB.receiveMethod(m);
    }
    public void foo () {}
} 

public class ClassB {
    public void receiveMethod (Method method) {
        Class c = method.getDeclaringClass();
    }

}

дает вам собственный класс.Экземпляр не имеет методов.

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