2011-04-01 33 views
2

在Java中,是否有可能访问方法所属的实例,只给出方法?如何访问在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... 
    } 
} 

我的感觉是方法属于类,一类没有实例,所以答案是否定的,但也许有一些偷偷摸摸的反射技术,我不知道。我总是可以通过'this'和foo方法一起传递,但这看起来像是额外的行李。

+1

我不记得能够通过类似的方法在我的Java ...然后再次,我有一段时间没有使用它。 – tster 2011-04-01 23:50:16

+2

你不能发送这样的方法; java没有函数指针,lambdas,委托或类似的东西。 – Kevin 2011-04-01 23:54:02

+0

hm,看起来你是对的 - 我来自一个主要的ActionScript背景,你可以*传递类似的方法。 – ericsoco 2011-04-01 23:56:57

回答

2

一种方法提供了有关信息,并获得,在一个类或接口的单个​​方法两者。反射方法可以是类方法或实例方法(包括抽象方法)。

一个方法允许在将实际参数与基础方法的形式参数调用匹配时扩展转换,但是如果发生缩小转换,则会引发IllegalArgumentException。

您可以拨打Method#invoke,但你会需要你想调用的方法的对象的实例,从方法DOC:

调用由此Method对象表示的基本方法 ,上 指定的对象与 指定的参数。单独的 参数被自动解包为 以匹配原始形式参数 并且原始参考和参考 参数都根据需要受方法 调用转换的支配。 如果底层方法是静态的, 然后指定obj参数是 忽略。它可能为空。

如果底层方法所需的形式参数 的数目是 0,所供给的args数组可以是 长度为0或空的。

如果底层方法是 实例方法,它是使用动态 方法查找如 记录调用的Java语言规范, 第二版,部分15.12.4.4;在 特别是,基于 的覆盖目标对象的运行时类型将发生 。

如果底层方法是静态的,即 声明的方法 初始化,如果它已不是 初始化类。

如果该方法正常完成,则返回的 值将返回给调用方的 调用方;如果该值具有 基元类型,则首先将 合适地包装在对象中。 然而,如果值具有 一个基本类型的数组的类型,所述阵列的 元件不包裹在对象 ;换言之,返回原始类型的数组 。如果 基础方法返回类型为void,则 的调用返回null。

所以TL:DR是除非你有你想要的实际对象你打电话的方法,这是不可能的。

0
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(); 
    } 

}

给你所属的类。一个实例不拥有方法。

+0

谢谢,但是这提供了拥有方法的* class *,而不是实例。 – ericsoco 2011-04-02 00:10:41

+0

对不起,没有看到你的笔记在底部。这是我的感觉 - 实例不拥有自己的方法。 – ericsoco 2011-04-02 00:13:43

0

这就像问:

“?鉴于从苹果园,这树拥有这个苹果一个苹果”

这个问题的答案是:

“不知道,因为所有的苹果树生产苹果,它可以属于任何树”。

...换句话说 - ,你必须提供一个实例从该方法将被调用

编辑

从您的意见之一,我收集你正在寻找一种替代的观察者模式。你说你不喜欢Observer模式的混乱,并且它对你来说不够“通用”。

我认为它可能是现存最不最麻烦的模式之一,并且接口在定义上与事物一样通用。

所以,也许是它的一个实现问题。幸运的是,我已经在JAVA上发布了Observer实现,以演示它的强大和优雅。

Polymorphism and Interfaces in Java (can polymorphism be used to implement interfaces...why?)

事实上:反射比混乱使用接口,因为你不能在编译时该对象的类型要调用一个方法的一个实例保证,甚至支持这种方法! (没有一些错误检查代码)。与接口相比,它甚至不可能有这个问题。

+0

@J T,我不是指Observer模式的混乱,我指的是不可避免地(?)在实现Observer接口的类的更新方法中发生的混乱。在ActionScript中,为观察者传递一个事件类型和一个方法给调度器(即Observable),并且调度器在调度指定类型的事件时直接调用该方法。在Observer.update中,观察者必须打开传入的对象(例如Event的类型)以确定如何响应。 – ericsoco 2011-04-02 01:56:03

+0

还有一点需要注意:可以认为AS的实现不如OOP,因为它将侦听器的方法暴露给另一个对象(调度器),该对象保持对这些方法的引用。但它为使用观察者模式提供了一个非常干净的API。我只是试图在Java中实现类似干净的(以我的观点来看)。 – ericsoco 2011-04-02 02:01:06

+1

@ericsoco:请参阅我对上一个问题的回答http://stackoverflow.com/q/4129280/591057 – 2011-04-02 02:33:17

0

你可以这样做,但在你的例子中正确的方法是使用interface,因为这似乎是你想要的:你想传入一个ClassB知道如何操作的对象。

interface Callback { 
     void foo(); 
    } 

    public class ClassA implements Callback {...} 

    public class ClassB { 
    public void receiveMethod(Callback cb) {...} 
    } 
+0

我需要比接口更通用的东西...我不想在这里详细讨论,因为这是提问,不讨论想法的地方(我已经被投票了为此之前)。但基本上我试图找到一种解决Observer.update内不可避免发生的混乱的方法。 – ericsoco 2011-04-02 00:15:38

+0

@ericsoco:嗯?观察者模式的混乱?它可能是现存最干净的模式之一。 Plus界面被定义为通用的。查看我的更新后的文章 – 2011-04-02 01:11:23

+0

您可以自由地将您想要在您自己的课程中调用它的实例包装在Method对象中。 – 2011-04-02 04:21:51

相关问题