Java 访问匿名类的构造函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/362424/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Accessing constructor of an anonymous class
提问by Saravanan M
Lets say I have a concrete class Class1 and I am creating an anonymous class out of it.
假设我有一个具体的 Class1 类,我正在用它创建一个匿名类。
Object a = new Class1(){
void someNewMethod(){
}
};
Now is there any way I could overload the constructor of this anonymous class. Like shown below
现在有什么方法可以重载这个匿名类的构造函数。如下图所示
Object a = new Class1(){
void someNewMethod(){
}
public XXXXXXXX(int a){
super();
System.out.println(a);
}
};
With something at xxxxxxxx to name the constructor?
用 xxxxxxxx 来命名构造函数?
采纳答案by Jon Skeet
From the Java Language Specification, section 15.9.5.1:
来自Java Language Specification,第 15.9.5.1 节:
An anonymous class cannot have an explicitly declared constructor.
匿名类不能有显式声明的构造函数。
Sorry :(
对不起 :(
EDIT: As an alternative, you can create some final local variables, and/or include an instance initializer in the anonymous class. For example:
编辑:作为替代方案,您可以创建一些最终局部变量,和/或在匿名类中包含一个实例初始值设定项。例如:
public class Test {
public static void main(String[] args) throws Exception {
final int fakeConstructorArg = 10;
Object a = new Object() {
{
System.out.println("arg = " + fakeConstructorArg);
}
};
}
}
It's grotty, but it might just help you. Alternatively, use a proper nested class :)
这很糟糕,但它可能只是帮助你。或者,使用适当的嵌套类:)
回答by Arne Burmeister
That is not possible, but you can add an anonymous initializer like this:
这是不可能的,但您可以添加一个匿名初始化程序,如下所示:
final int anInt = ...;
Object a = new Class1()
{
{
System.out.println(anInt);
}
void someNewMethod() {
}
};
Don't forget final on declarations of local variables or parameters used by the anonymous class, as i did it for anInt.
不要忘记匿名类使用的局部变量或参数声明的 final,就像我为 anInt 所做的那样。
回答by Ilja Preu?
It doesn't make any sense to have a named overloaded constructor in an anonymous class, as there would be no way to call it, anyway.
在匿名类中使用命名的重载构造函数没有任何意义,因为无论如何都无法调用它。
Depending on what you are actually trying to do, just accessing a final local variable declared outside the class, or using an instance initializer as shown by Arne, might be the best solution.
根据您实际尝试执行的操作,仅访问在类外声明的最终局部变量,或使用 Arne 所示的实例初始值设定项,可能是最佳解决方案。
回答by Ilja Preu?
Yes , It is right that you can not define construct in an Anonymous class but it doesn't mean that anonymous class don't have constructor. Confuse... Actually you can not define construct in an Anonymous class but compiler generates an constructor for it with the same signature as its parent constructor called. If the parent has more than one constructor, the anonymous will have one and only one constructor
是的,您不能在匿名类中定义构造是正确的,但这并不意味着匿名类没有构造函数。混淆...实际上你不能在匿名类中定义构造,但编译器为它生成一个构造函数,其签名与其父构造函数调用的签名相同。如果父级有多个构造函数,则匿名者将只有一个构造函数
回答by Joel Shemtov
Here's another way around the problem:
这是解决问题的另一种方法:
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();
}
}
回答by arnaldocan
In my case, a local class (with custom constructor) worked as an anonymous class:
就我而言,本地类(带有自定义构造函数)作为匿名类工作:
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;
}
回答by Whimusical
If you dont need to pass arguments, then initializer code is enough, but if you need to pass arguments from a contrcutor there is a way to solve most of the cases:
如果您不需要传递参数,那么初始化代码就足够了,但是如果您需要从构造函数传递参数,则有一种方法可以解决大多数情况:
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);
回答by Peter Verhas
You can have a constructor in the abstract class that accepts the init parameters. The Java spec only specifies that the anonymous class, which is the offspring of the (optionally) abstract class or implementation of an interface, can not have a constructor by her own right.
您可以在接受 init 参数的抽象类中有一个构造函数。Java 规范仅指定作为(可选)抽象类或接口实现的后代的匿名类不能凭自己的权利拥有构造函数。
The following is absolutely legal and possible:
以下是绝对合法和可能的:
static abstract class Q{
int z;
Q(int z){ this.z=z;}
void h(){
Q me = new Q(1) {
};
}
}
If you have the possibility to write the abstract class yourself, put such a constructor there and use fluent API where there is no better solution. You can this way override the constructor of your original class creating an named sibling class with a constructor with parameters and use that to instantiate your anonymous class.
如果您有可能自己编写抽象类,请将这样的构造函数放在那里,并在没有更好解决方案的地方使用 fluent API。您可以通过这种方式覆盖原始类的构造函数,创建一个带有参数的构造函数的命名兄弟类,并使用它来实例化您的匿名类。
回答by Diogo Quintela
Peter Norvig's The Java IAQ: Infrequently Answered Questions
Peter Norvig 的 Java IAQ:不常回答的问题
http://norvig.com/java-iaq.html#constructors- Anonymous class contructors
http://norvig.com/java-iaq.html#constructors- 匿名类构造器
http://norvig.com/java-iaq.html#init- Construtors and initialization
http://norvig.com/java-iaq.html#init- 构造函数和初始化
Summing, you can construct something like this..
总而言之,你可以构建这样的东西..
public class ResultsBuilder {
Set<Result> errors;
Set<Result> warnings;
...
public Results<E> build() {
return new Results<E>() {
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;
}
}
回答by Thirumalai Parthasarathi
I know the thread is too old to post an answer. But still i think it is worth it.
我知道该线程太旧,无法发布答案。但我仍然认为这是值得的。
Though you can't have an explicit constructor, if your intention is to call the constructor of the super class, then the following is all you have to do.
虽然你不能有一个显式的构造函数,但如果你的意图是调用超类的构造函数,那么下面就是你所要做的。
StoredProcedure sp = new StoredProcedure(datasource, spName) {
{// init code if there are any}
};
This is an example of creating a StoredProcedure
object in Spring by passing a DataSource
and a String
object.
这是StoredProcedure
在 Spring 中通过传递 aDataSource
和一个String
对象来创建对象的示例。
So the Bottom line is, if you want to create an anonymous class and want to call the super class constructor then create the anonymous class with a signature matching the super class constructor.
所以底线是,如果你想创建一个匿名类并想要调用超类构造函数,那么创建一个签名与超类构造函数匹配的匿名类。