¿Es siquiera posible?
Respuestas:
si te refieres a una función anónima y estás usando una versión de Java anterior a Java 8, entonces en una palabra, no. ( Lea acerca de las expresiones lambda si usa Java 8+ )
Sin embargo, puede implementar una interfaz con una función como esta:
Comparator<String> c = new Comparator<String>() {
int compare(String s, String s2) { ... }
};
y puede usar esto con clases internas para obtener una función casi anónima :)
Aquí hay un ejemplo de una clase interna anónima.
System.out.println(new Object() {
@Override public String toString() {
return "Hello world!";
}
}); // prints "Hello world!"
Esto no es muy útil tal como está, pero muestra cómo crear una instancia de una clase interna anónima extends Object
y @Override
su toString()
método.
Las clases internas anónimas son muy útiles cuando necesita implementar una interface
que puede no ser altamente reutilizable (y por lo tanto no vale la pena refactorizarla a su propia clase nombrada). Un ejemplo instructivo es el uso de una costumbre java.util.Comparator<T>
para ordenar.
Aquí tienes un ejemplo de cómo puedes ordenar un String[]
archivo String.length()
.
import java.util.*;
//...
String[] arr = { "xxx", "cd", "ab", "z" };
Arrays.sort(arr, new Comparator<String>() {
@Override public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
});
System.out.println(Arrays.toString(arr));
// prints "[z, cd, ab, xxx]"
Tenga en cuenta el truco de comparación por resta que se utiliza aquí. Hay que decir que esta técnica está rota en general: solo es aplicable cuando se puede garantizar que no se desbordará (tal es el caso de las String
longitudes).
EventListener
(sub) implementaciones en la aplicación Swing promedio.
Linked
barra lateral, así que estoy haciendo todo lo posible para usarla.
Con la introducción de la expresión lambda en Java 8, ahora puede tener métodos anónimos.
Digamos que tengo una clase Alpha
y quiero filtrar Alpha
mensajes en una condición específica. Para hacer esto, puede usar un Predicate<Alpha>
. Esta es una interfaz funcional que tiene un método test
que acepta un Alpha
y devuelve un boolean
.
Suponiendo que el método de filtro tiene esta firma:
List<Alpha> filter(Predicate<Alpha> filterPredicate)
Con la antigua solución de clase anónima, necesitaría algo como:
filter(new Predicate<Alpha>() {
boolean test(Alpha alpha) {
return alpha.centauri > 1;
}
});
Con las lambdas de Java 8 puedes hacer:
filter(alpha -> alpha.centauri > 1);
Para obtener información más detallada, consulte el tutorial de expresiones Lambda
Las clases internas anónimas que implementan o extienden la interfaz de un tipo existente se han realizado en otras respuestas, aunque vale la pena señalar que se pueden implementar múltiples métodos (a menudo con eventos de estilo JavaBean, por ejemplo).
Una característica poco reconocida es que aunque las clases internas anónimas no tienen un nombre, sí tienen un tipo. Se pueden agregar nuevos métodos a la interfaz. Estos métodos solo se pueden invocar en casos limitados. Principalmente directamente en la new
expresión en sí y dentro de la clase (incluidos los inicializadores de instancia). Puede confundir a los principiantes, pero puede ser "interesante" para la recursividad.
private static String pretty(Node node) {
return "Node: " + new Object() {
String print(Node cur) {
return cur.isTerminal() ?
cur.name() :
("("+print(cur.left())+":"+print(cur.right())+")");
}
}.print(node);
}
(Originalmente escribí esto usando en node
lugar de cur
en el print
método. ¿ Di NO a capturar final
locales "implícitamente "? )
node
debe declararse final
aquí.
cur
.
"Node" +
para hacer necesario un segundo método). / No tengo nombre. Quizás podría crear una pregunta de "encuesta" de nombres (CW), y hacer que se rechace en el olvido.
Sí, si está utilizando la última versión de Java, que es la versión 8. Java8 permite definir funciones anónimas que era imposible en versiones anteriores.
Tomemos un ejemplo de los documentos de Java para saber cómo podemos declarar funciones anónimas, clases
El siguiente ejemplo, HelloWorldAnonymousClasses, usa clases anónimas en las declaraciones de inicialización de las variables locales frenchGreeting y spanishGreeting, pero usa una clase local para la inicialización de la variable englishGreeting:
public class HelloWorldAnonymousClasses {
interface HelloWorld {
public void greet();
public void greetSomeone(String someone);
}
public void sayHello() {
class EnglishGreeting implements HelloWorld {
String name = "world";
public void greet() {
greetSomeone("world");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Hello " + name);
}
}
HelloWorld englishGreeting = new EnglishGreeting();
HelloWorld frenchGreeting = new HelloWorld() {
String name = "tout le monde";
public void greet() {
greetSomeone("tout le monde");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Salut " + name);
}
};
HelloWorld spanishGreeting = new HelloWorld() {
String name = "mundo";
public void greet() {
greetSomeone("mundo");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Hola, " + name);
}
};
englishGreeting.greet();
frenchGreeting.greetSomeone("Fred");
spanishGreeting.greet();
}
public static void main(String... args) {
HelloWorldAnonymousClasses myApp =
new HelloWorldAnonymousClasses();
myApp.sayHello();
}
}
Sintaxis de clases anónimas
Considere la instanciación del objeto frenchGreeting:
HelloWorld frenchGreeting = new HelloWorld() {
String name = "tout le monde";
public void greet() {
greetSomeone("tout le monde");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Salut " + name);
}
};
La expresión de clase anónima consta de lo siguiente:
new
operadorEl nombre de una interfaz para implementar o una clase para extender. En este ejemplo, la clase anónima está implementando la interfaz HelloWorld.
Paréntesis que contienen los argumentos de un constructor, como una expresión de creación de instancia de clase normal. Nota: cuando implementa una interfaz, no hay un constructor, por lo que usa un par de paréntesis vacíos, como en este ejemplo.
Un cuerpo, que es un cuerpo de declaración de clase. Más específicamente, en el cuerpo, las declaraciones de métodos están permitidas pero las declaraciones no.