我可以这样做:
new Object(){
public void hi(){}
}.hi();
我(或我可以)如何做到这一点:
IWouldRatherStayAnonymous t = new IWouldRatherStayAnonymous extends Thread(){
public void NoNoYouCantCallMe(String s){}
};
t.NoNoYouCantCallMe("some useful data that i will need later, but don't want to save this anonymous class");
如果我不能在语法上做到这一点,任何人都可以解释逻辑/实现设计,为什么这将永远不会工作?
==========================================
编辑:澄清 - 我想创建一个匿名类而不保存它,然后实例化该匿名类的实例。我只需要1个引用,因为我不打算经常使用这个引用(即使在同一个外部类中也不想使用它)。但是,我只想将一些数据传递给这个匿名类只有一次(理想情况下是构造函数,但你会注意到你实际上不能覆盖Thread()中的构造函数)。
这真的不是一个巨大的交易,我只是好奇这是否可行,但似乎从一些答案可行,但不是很漂亮。
答案 0 :(得分:3)
你的问题有点令人困惑,但听起来你想要一个扩展Thread
并实现某个接口的类,但是在它所使用的方法之外无法访问它(这将规则甚至私有嵌套类)。在这种情况下,请使用local class:
void myMethod() {
class Impl extends Thread implements SomeInterface {
@Override
public void someInterfaceMethod(String s){ }
}
new Impl().someInterfaceMethod("data");
}
编辑:为了响应您的更新,您可以自然地为本地类提供构造函数并传入数据,或者让它关闭外部方法中的final
个变量。 / p>
答案 1 :(得分:2)
如果我不能在语法上做到这一点,任何人都可以解释 逻辑/实现设计,为什么这将永远不起作用?
我可以解释一下。如果Java中有表达式foo.bar(...)
,则编译器必须确保表达式foo
的静态(编译时)类型支持方法bar()
。在第一种情况下,左边的表达式是匿名类创建表达式,因此它的静态类型是具有该方法的匿名类。
但是,在第二种情况下,左边的表达式是一个变量。变量的静态类型是声明变量的类型。在Java中,必须使用显式类型声明变量(与其他语言一样,不是var
或auto
)。因此,其静态类型必须是命名类型。 Thread
并且没有其他命名类型支持方法NoNoYouCantCallMe()
;只有匿名类支持此方法,并且您不能声明匿名类类型的变量。这就是为什么它在语法上不可能。
但是,我想简单地将一些数据传递给匿名者 类只有一次(理想情况下是构造函数,但你会注意到你 实际上不能覆盖Thread()中的构造函数。
这很简单。您不需要将数据显式传递到匿名类,因为在匿名类和本地类中,您可以自动访问周围范围内的final
变量。因此,您只需直接使用外部数据,而不是传入数据。
final String someData = "blah";
Thread t = new Thread() {
public void run() { doStuffWith(someData); }
};
答案 2 :(得分:1)
有两种方法可以访问匿名类的方法:
Java做not provide a way of capturing the type of the anonymous class statically,例如以类似于C#的var
关键字的方式。
在您的情况下,您可以使用void NoNoYouCantCallMe(String)
方法创建抽象类型,并使用该类作为匿名类的基础,如下所示:
abstract class MyThreadBase extends Thread {
public abstract void YesICanCallYou(String s);
}
...
MyThreadBase t = new MyThreadBase() {
public void YesICanCallYou(String s){}
};
...
t.YesICanCallYou();
答案 3 :(得分:1)
你可以创建一个内部类,只是不要匿名。匿名意味着您没有类型。
我建议在同一个文件中使用命名的内部类或第二个类。我经常使用第二种,它不能公开。
答案 4 :(得分:1)
如果真的想要在不使用界面或抽象类的情况下做一些像这样的淫秽,你可以通过反思来调用它:
@Test
public void testCrazyStuff() throws IllegalArgumentException, SecurityException,
IllegalAccessException, InvocationTargetException, NoSuchMethodException
{
Object object = new Thread()
{
public void ICanBeCalled( String s )
{
System.out.println( s );
}
};
object.getClass()
.getMethod( "ICanBeCalled", String.class )
.invoke( object, "Whatever string!" );
}
但这没有意义......最好采用一个简单的解决方案来设置接口或抽象类,就像其他建议一样。
答案 5 :(得分:1)
您可以使用自由变量捕获将数据传递给匿名内部类,将要捕获其值的任何变量声明为final
:
public void myFunction(final int magicNumber) {
new Thread() {
@Override public void run() {
System.out.println("I can access the magic number: " + magicNumber);
}
}.start();
}
答案 6 :(得分:0)
一种选择是声明匿名类可以实现的单个抽象类:
public interface IDontWorkForSomeReasonThread {
public void NoNoYouCantCallMe(String s);
}
public static abstract class MyAbstractThread
extends Thread
implements IDontWorkForSomeReasonThread { }
public static void main (String[] args) throws java.lang.Exception {
IDontWorkForSomeReasonThread t = new MyAbstractThread() {
public void NoNoYouCantCallMe(String s){}
};
t.NoNoYouCantCallMe( "foo" );
}