Java 访问匿名类的构造函数

Java 访问匿名类的构造函数,java,constructor,overloading,anonymous-types,Java,Constructor,Overloading,Anonymous Types,假设我有一个具体的类Class1,我正在用它创建一个匿名类 Object a = new Class1(){ void someNewMethod(){ } }; 现在我有没有办法重载这个匿名类的构造函数。如下图所示 Object a = new Class1(){ void someNewMethod(){ } public XXXXXXXX(int a){ super();

假设我有一个具体的类Class1,我正在用它创建一个匿名类

Object a = new Class1(){
        void someNewMethod(){
        }
      };
现在我有没有办法重载这个匿名类的构造函数。如下图所示

Object a = new Class1(){
        void someNewMethod(){
        }
        public XXXXXXXX(int a){
          super();
          System.out.println(a);
        }
      };
在xxxxxxxx处用某物命名构造函数?

来自第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);
            }
        };
    }
}

这很糟糕,但可能对您有所帮助。或者,使用适当的嵌套类:)

这是不可能的,但您可以添加如下匿名初始值设定项:

final int anInt = ...;
Object a = new Class1()
{
  {
    System.out.println(anInt);
  }

  void someNewMethod() {
  }
};

不要忘记匿名类使用的局部变量或参数声明的final,就像我为anInt所做的那样。

在匿名类中使用命名重载构造函数没有任何意义,因为无论如何都无法调用它


根据您实际尝试的操作,仅访问类外声明的最终局部变量,或使用Arne所示的实例初始值设定项,可能是最佳解决方案。

是的,您不能在匿名类中定义构造函数,但这并不意味着匿名类没有构造函数。混淆
实际上,您不能在匿名类中定义构造函数,但编译器会为它生成一个构造函数,其签名与其调用的父构造函数相同。如果父对象有多个构造函数,匿名对象将有一个且只有一个构造函数

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();
    }
}
在我的例子中,本地类(带有自定义构造函数)作为匿名类工作:

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;
}

如果您不需要传递参数,那么初始化器代码就足够了,但是如果您需要从Contractor传递参数,有一种方法可以解决大多数情况:

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);

您可以在接受init参数的抽象类中有一个构造函数。Java规范只规定匿名类(可选)是抽象类或接口实现的后代,不能单独拥有构造函数

以下是绝对合法和可能的:

static abstract class Q{
    int z;
    Q(int z){ this.z=z;}
    void h(){
        Q me = new Q(1) {
        };
    }
}

如果您有可能自己编写抽象类,那么就把这样的构造函数放在那里,并在没有更好解决方案的地方使用fluentapi。您可以通过这种方式覆盖原始类的构造函数,创建一个带有参数的构造函数的命名同级类,并使用该构造函数实例化匿名类。

Peter Norvig的《Java IAQ:不常回答的问题》

-匿名类构造函数

-构造函数和初始化

总的来说,你可以构造这样的东西

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;
    }
}
公共类结果生成器{
设置错误;
设置警告;
...
公共成果构建(){
返回新结果(){
私有结果[]错误视图;
私有结果[]警告视图;
{
errorsView=ResultsBuilder.this.getErrors();
WarningView=ResultsBuilder.this.getWarnings();
}
公共结果[]getErrors(){
返回错误视图;
}
公共结果[]获取警告(){
返回警告视图;
}
};
}
公共结果[]getErrors(){
return!isEmpty(this.errors)?errors.toArray(新结果[0]):null;
}
公共结果[]获取警告(){
return!isEmpty(this.warnings)?warnings.toArray(新结果[0]):null;
}
}

我知道该线程太旧,无法发布答案。但我仍然认为这是值得的

虽然您不能有一个显式构造函数,但是如果您的目的是调用这个超类的构造函数,那么您只需要执行以下操作

StoredProcedure sp = new StoredProcedure(datasource, spName) {
    {// init code if there are any}
};
这是通过传递
数据源
字符串
对象在Spring中创建对象的示例


所以底线是,如果你想创建一个匿名类并调用超级类构造函数,然后创建一个签名与超级类构造函数匹配的匿名类,我相信他没有复制它。他对java有足够的了解,公平地说,当他复制它的时候,他会给予赞扬。天哪,有人指责Jon Skeet复制了它吗?我怎么能从println内部调用测试超类中的方法,当这个方法被重写时?@Zom-B:还不清楚你到底是什么意思-我怀疑你值得问一个新问题,并举例说明你试图实现什么。啊,我想重写超类构造函数。。。然后我明白了
no显式声明的
ctor也意味着不重写任何内容。我想,如果需要,该语言可以很容易地将“普通”构造函数参数转换为匿名类的参数。构造器声明的语法可能看起来很奇怪……难道它不能像基类构造器那样声明构造器吗?我看不出这个很好的解决方案有什么问题,但这里使用的线程一开始会让人产生误解(有一段时间我以为您创建了一个单独的线程来初始化东西!)请注意,定义了
t
之后,您不能调用
t.initialise()
除非该函数是在类/接口类型中定义的。@AramKocharyan使其工作起来更像一个构造函数。我喜欢这个解决方案!显然,
initialise()
方法是在线程构造函数之后调用的。另一方面,(至少对我来说)不明显的是,使用实例初始值设定项总是可以保证这一点。如果父级有构造函数,那么值得一读:如果我理解您的代码,anonymousClass应该从String继承(setVar是String的类型并返回此值),但String是不可扩展的。我想setVar应该