Estoy buscando implementar una funcionalidad en una lista de objetos como lo haría en C # usando un método de extensión.
Algo como esto:
List<DataObject> list;
// ... List initialization.
list.getData(id);
¿Cómo hago eso en Java?
java
extension-methods
Fabio Milheiro
fuente
fuente
Respuestas:
Java no admite métodos de extensión.
En cambio, puede hacer un método estático regular o escribir su propia clase.
fuente
Los métodos de extensión no son solo métodos estáticos y no solo azúcar de sintaxis de conveniencia, de hecho son una herramienta bastante poderosa. Lo principal es la capacidad de anular diferentes métodos basados en la creación de instancias de diferentes parámetros genéricos. Esto es similar a las clases de tipo de Haskell y, de hecho, parece que están en C # para admitir las mónadas de C # (es decir, LINQ). Incluso dejando caer la sintaxis de LINQ, todavía no conozco ninguna forma de implementar interfaces similares en Java.
Y no creo que sea posible implementarlos en Java, debido a la semántica de borrado tipo Java de los parámetros genéricos.
fuente
Project Lombok proporciona una anotación
@ExtensionMethod
que se puede utilizar para lograr la funcionalidad que está solicitando.fuente
java.lang.String
. Demostración: http://manifold.systems/images/ExtensionMethod.mp4Técnicamente, la extensión C # no tiene equivalente en Java. Pero si desea implementar tales funciones para un código más limpio y fácil de mantener, debe usar el marco de Manifold.
fuente
El lenguaje XTend , que es un superconjunto de Java y se compila en el código fuente 1 de Java , lo admite.
fuente
Manifold proporciona Java con métodos de extensión de estilo C # y varias otras características. A diferencia de otras herramientas, colector no tiene limitaciones y no sufren de problemas con los genéricos, lambdas, etc. IDE colector proporciona varias otras características tales como F # al estilo de tipos personalizados , de estilo mecanografiado las interfaces estructurales y de estilo Javascript tipos expando .
Además, IntelliJ proporciona soporte integral para Manifold a través del complemento Manifold .
Manifold es un proyecto de código abierto disponible en github .
fuente
Otra opción es usar las clases ForwardingXXX de la biblioteca google-guava.
fuente
Java no tiene esa característica. En su lugar, puede crear una subclase regular de la implementación de su lista o crear una clase interna anónima:
El problema es llamar a este método. Puedes hacerlo "en su lugar":
fuente
Parece que hay una pequeña posibilidad de que los métodos de defensa (es decir, los métodos predeterminados) puedan ingresar a Java 8. Sin embargo, hasta donde yo los entiendo, solo permiten que el autor de un lo
interface
extienda retroactivamente, no usuarios arbitrarios.Los métodos de defensa + inyección de interfaz podrían implementar completamente los métodos de extensión de estilo C #, pero AFAICS, la inyección de interfaz ni siquiera está en la hoja de ruta de Java 8 todavía.
fuente
Un poco tarde para la fiesta en esta pregunta, pero en caso de que alguien lo encuentre útil, acabo de crear una subclase:
fuente
Podemos simular la implementación de los métodos de extensión de C # en Java utilizando la implementación del método predeterminado disponible desde Java 8. Comenzamos definiendo una interfaz que nos permitirá acceder al objeto de soporte a través de un método base (), de esta manera:
Devolvemos nulo ya que las interfaces no pueden tener estado, pero esto tiene que repararse más tarde a través de un proxy.
El desarrollador de extensiones tendría que extender esta interfaz mediante una nueva interfaz que contenga métodos de extensión. Supongamos que queremos agregar una interfaz para cada consumidor en la Lista:
Debido a que ampliamos la interfaz de Extensión, podemos llamar al método base () dentro de nuestro método de extensión para acceder al objeto de soporte al que nos adjuntamos.
La interfaz de extensión debe tener un método de fábrica que creará una extensión de un objeto de soporte dado:
Creamos un proxy que implementa la interfaz de extensión y toda la interfaz implementada por el tipo del objeto de soporte. El controlador de invocación dado al proxy distribuiría todas las llamadas al objeto de soporte, excepto el método "base", que debe devolver el objeto de soporte, de lo contrario su implementación predeterminada devolverá nulo:
Luego, podemos usar el método Extension.create () para adjuntar la interfaz que contiene el método de extensión al objeto de soporte. El resultado es un objeto que puede ser lanzado a la interfaz de extensión por el cual todavía podemos acceder al objeto de soporte que llama al método base (). Al tener la referencia convertida en la interfaz de extensión, ahora podemos llamar con seguridad a los métodos de extensión que pueden tener acceso al objeto de soporte, de modo que ahora podemos adjuntar nuevos métodos al objeto existente, pero no a su tipo de definición:
Entonces, esta es una forma en que podemos simular la capacidad de extender objetos en Java al agregarles nuevos contratos, lo que nos permite llamar a métodos adicionales en los objetos dados.
A continuación puede encontrar el código de la interfaz de Extensión:
fuente
Se podría usar el patrón de diseño orientado a objetos decorador . Un ejemplo de este patrón que se usa en la biblioteca estándar de Java sería DataOutputStream .
Aquí hay un código para aumentar la funcionalidad de una Lista:
PD: Soy un gran admirador de Kotlin . Tiene métodos de extensión y también se ejecuta en la JVM.
fuente
Puede crear un método auxiliar / extensión similar a C # mediante (RE) implementando la interfaz de Colecciones y agregando un ejemplo para la Colección Java:
fuente
Java
8 ahora admite métodos predeterminados , que son similares aC#
los métodos de extensión de.fuente