java - 访问匿名类的构造函数
假设我有一个具体的类Class1,我正在创建一个匿名类。
Object a = new Class1(){
void someNewMethod(){
}
};
现在有什么办法可以重载这个匿名类的构造函数。 如下图所示
Object a = new Class1(){
void someNewMethod(){
}
public XXXXXXXX(int a){
super();
System.out.println(a);
}
};
用xxxxxxxx命名构造函数?
10个解决方案
258 votes
从Java语言规范,第15.9.5.1节:
一个匿名类不能拥有 显式声明的构造函数。
对不起:(
编辑:作为替代方案,您可以创建一些最终的局部变量,和/或在匿名类中包含实例初始化程序。 例如:
public class Test {
public static void main(String[] args) throws Exception {
final int fakeConstructorArg = 10;
Object a = new Object() {
{
System.out.println("arg = " + fakeConstructorArg);
}
};
}
}
这很糟糕,但它可能只对你有所帮助。 或者,使用适当的嵌套类:)
Jon Skeet answered 2019-03-17T20:19:12Z
93 votes
这是不可能的,但你可以像这样添加一个匿名的初始化器:
final int anInt = ...;
Object a = new Class1()
{
{
System.out.println(anInt);
}
void someNewMethod() {
}
};
不要忘记最后对匿名类使用的局部变量或参数的声明,就像我为anInt所做的那样。
Arne Burmeister answered 2019-03-17T20:19:42Z
68 votes
这是解决问题的另一种方法:
public class Test{
public static final void main(String...args){
new Thread(){
private String message = null;
Thread initialise(String message){
this.message = message;
return this;
}
public void run(){
System.out.println(message);
}
}.initialise(args[0]).start();
}
}
Joel Shemtov answered 2019-03-17T20:20:05Z
13 votes
我知道这个帖子太旧了,无法发布答案。 但我仍然认为这是值得的。
虽然你不能有一个显式的构造函数,但如果你打算调用超类的构造函数,那么你需要做的就是以下内容。
StoredProcedure sp = new StoredProcedure(datasource, spName) {
{// init code if there are any}
};
这是通过传递DataSource和String对象在Spring中创建DataSource对象的示例。
所以底线是,如果你想创建一个匿名类并想要调用超类构造函数,那么创建一个带有与超类构造函数匹配的签名的匿名类。
Thirumalai Parthasarathi answered 2019-03-17T20:20:49Z
3 votes
您可以在抽象类中拥有一个接受init参数的构造函数。 Java规范只规定匿名类是(可选)抽象类或接口实现的后代,它本身不能拥有构造函数。
以下是绝对合法和可能的:
static abstract class Q{
int z;
Q(int z){ this.z=z;}
void h(){
Q me = new Q(1) {
};
}
}
如果你有可能自己编写抽象类,那就把这样的构造函数放在那里,并使用流畅的API,没有更好的解决方案。 您可以通过这种方式覆盖原始类的构造函数,使用带参数的构造函数创建一个名为sibling的类,并使用它来实例化您的匿名类。
Peter Verhas answered 2019-03-17T20:21:28Z
2 votes
是的,你不能在Anonymous类中定义构造是正确的,但这并不意味着匿名类没有构造函数。 迷惑...实际上你不能在Anonymous类中定义构造,但是编译器为它生成一个构造函数,其签名与其父构造函数相同。 如果父项具有多个构造函数,则匿名将只有一个构造函数
answered 2019-03-17T20:21:53Z
2 votes
如果你不需要传递参数,那么初始化代码就足够了,但是如果你需要从一个控制器传递参数,有一种方法可以解决大多数情况:
Boolean var= new anonymousClass(){
private String myVar; //String for example
@Overriden public Boolean method(int i){
//use myVar and i
}
public String setVar(String var){myVar=var; return this;} //Returns self instane
}.setVar("Hello").method(3);
Whimusical answered 2019-03-17T20:22:17Z
2 votes
Peter Norvig的Java IAQ:不经常回答的问题
[http://norvig.com/java-iaq.html#constructors] - 匿名类构造函数
[http://norvig.com/java-iaq.html#init] - 构造函数和初始化
求和,你可以构造这样的东西..
public class ResultsBuilder {
Set errors;
Set warnings;
...
public Results build() {
return new Results() {
private Result[] errorsView;
private Result[] warningsView;
{
errorsView = ResultsBuilder.this.getErrors();
warningsView = ResultsBuilder.this.getWarnings();
}
public Result[] getErrors() {
return errorsView;
}
public Result[] getWarnings() {
return warningsView;
}
};
}
public Result[] getErrors() {
return !isEmpty(this.errors) ? errors.toArray(new Result[0]) : null;
}
public Result[] getWarnings() {
return !isEmpty(this.warnings) ? warnings.toArray(new Result[0]) : null;
}
}
Diogo Quintela answered 2019-03-17T20:23:01Z
1 votes
在匿名类中有一个名为重载的构造函数没有任何意义,因为无论如何都无法调用它。
根据您实际尝试的操作,只需访问在类外部声明的最终局部变量,或使用Arne所示的实例初始化程序,可能是最佳解决方案。
Ilja Preuß answered 2019-03-17T20:23:31Z
1 votes
在我的例子中,本地类(使用自定义构造函数)作为匿名类工作:
Object a = getClass1(x);
public Class1 getClass1(int x) {
class Class2 implements Class1 {
void someNewMethod(){
}
public Class2(int a){
super();
System.out.println(a);
}
}
Class1 c = new Class2(x);
return c;
}
arnaldocan answered 2019-03-17T20:23:55Z