Construtor de acesso de uma classe anónima
Object a = new Class1(){
void someNewMethod(){
}
};
Há alguma forma de sobrecarregar o construtor desta aula anónima? Como mostrado abaixo
Object a = new Class1(){
void someNewMethod(){
}
public XXXXXXXX(int a){
super();
System.out.println(a);
}
};
Com algo em xxxxxxxx para nomear o construtor?
10 answers
Da especificação da linguagem Java , secção 15.9.5.1:
Uma classe anónima não pode ter um construtor declarado explicitamente.Desculpa.
Editar: em alternativa, poderá criar algumas variáveis locais finais e/ou incluir um inicializador de instância na classe anónima. Por exemplo:
public class Test {
public static void main(String[] args) throws Exception {
final int fakeConstructorArg = 10;
Object a = new Object() {
{
System.out.println("arg = " + fakeConstructorArg);
}
};
}
}
É grotesco, mas pode ajudar-te. Em alternativa, utilize uma classe aninhada adequada:)
final int anInt = ...;
Object a = new Class1()
{
{
System.out.println(anInt);
}
void someNewMethod() {
}
};
Não se esqueça das declarações finais de variáveis locais ou parâmetros usados pela classe anônima, como eu fiz para o anInt.
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();
}
}
Embora você não possa ter um construtor explícito, Se sua intenção é chamar o construtor da super classe, então o seguinte é tudo que você tem que fazer.
StoredProcedure sp = new StoredProcedure(datasource, spName) {
{// init code if there are any}
};
Este é um exemplo de criação de um StoredProcedure
object in Spring by passing a DataSource
and a String
object.
Então, a questão é, se você quer criar uma classe anônima e quer chamar o super o construtor de Classes cria então a classe anónima com uma assinatura correspondente ao construtor de super classes.
Você pode ter um construtor na classe abstrata que aceita os parâmetros init. O Java spec apenas especifica que a classe anônima, que é a prole da classe abstrata (opcionalmente) ou implementação de uma interface, não pode ter um construtor por seu próprio direito.
O seguinte é absolutamente legal e possível:
static abstract class Q{
int z;
Q(int z){ this.z=z;}
void h(){
Q me = new Q(1) {
};
}
}
Se você tem a possibilidade de escrever a classe abstrata, coloque lá um construtor e use a API fluente onde não existe solucao. Você pode assim anular o construtor da sua classe original criando uma classe de irmãos com nome com um construtor com parâmetros e usá-los para instanciar a sua classe anônima.
Se você não precisa passar argumentos, então o código de inicialização é suficiente, mas se você precisa passar argumentos de um contratutor há uma maneira de resolver a maioria dos casos:
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);
Peter Norvig é o QIAQ Java: Respostas Pouco frequentes
Http://norvig.com/java-iaq.html#constructors - contratores anónimos de classe
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;
}
}
Dependendo do que você está realmente tentando fazer, apenas acessar uma variável local final declarada fora da classe, ou usando um inicializador de instância como mostrado por Arne, pode ser a melhor solução.
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;
}