titledborder icon example borderfactory java interface java-8 default

icon - ¿Cuál es el propósito de la palabra clave predeterminada en Java?



set icon java (8)

Una interfaz en Java es similar a una clase, pero el cuerpo de una interfaz solo puede incluir métodos abstractos y campos final (constantes).

Recientemente, vi una pregunta, que se ve así

interface AnInterface { public default void myMethod() { System.out.println("D"); } }

Según la definición de la interfaz, solo se permiten métodos abstractos . ¿Por qué me permite compilar el código anterior? ¿Cuál es la palabra clave default ?

Por otro lado, cuando intentaba escribir el siguiente código, dice que el modifier default not allowed here

default class MyClass{ }

en lugar de

class MyClass { }

¿Alguien puede decirme el propósito de la palabra clave default ? ¿Solo se permite dentro de una interfaz? ¿En qué difiere del default (sin modificador de acceso)?


Algo que se pasó por alto en las otras respuestas fue su papel en las anotaciones. Ya en Java 1.5, la palabra clave default surgió como un medio para proporcionar un valor predeterminado para un campo de anotación.

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Processor { String value() default "AMD"; }

Su uso se sobrecargó con la introducción de Java 8 para permitir que uno defina un método predeterminado en las interfaces.

Algo más que se pasó por alto: la razón por la que la default class MyClass {} declaración default class MyClass {} no es válida se debe a la forma en que se declaran las clases . No hay ninguna disposición en el idioma que permita que esa palabra clave aparezca allí. Sin embargo , aparece para las declaraciones de métodos de interfaz .


Encontrará una muy buena explicación en The Java ™ Tutorials , parte de la explicación es la siguiente:

Considere un ejemplo que involucra a fabricantes de automóviles controlados por computadora que publican interfaces estándar de la industria que describen qué métodos pueden invocarse para operar sus automóviles. ¿Qué pasa si esos fabricantes de automóviles controlados por computadora agregan nuevas funcionalidades, como el vuelo, a sus automóviles? Estos fabricantes necesitarían especificar nuevos métodos para permitir que otras compañías (como los fabricantes de instrumentos de guía electrónica) adapten su software a los autos voladores. ¿Dónde declararían estos fabricantes de automóviles estos nuevos métodos relacionados con el vuelo? Si los agregan a sus interfaces originales, entonces los programadores que han implementado esas interfaces tendrían que reescribir sus implementaciones. Si los agregan como métodos estáticos, los programadores los considerarían como métodos de utilidad, no como métodos esenciales esenciales.

Los métodos predeterminados le permiten agregar nuevas funciones a las interfaces de sus bibliotecas y garantizar la compatibilidad binaria con el código escrito para versiones anteriores de esas interfaces.


Es una nueva característica en Java 8 que permite que una interface proporcione una implementación. Descrito en Java 8 JLS-13.5.6. Declaraciones de método de interfaz que lee (en parte)

Agregar un método default , o cambiar un método de abstract a default , no rompe la compatibilidad con los binarios preexistentes, pero puede causar un IncompatibleClassChangeError si un binario preexistente intenta invocar el método. Este error ocurre si el tipo de calificación, T , es un subtipo de dos interfaces, I y J , donde I y J declaran un método default con la misma firma y resultado, y ni I ni J son una subinterfaz de la otra.

What''s New in JDK 8 dice (en parte)

Los métodos predeterminados permiten agregar nuevas funciones a las interfaces de las bibliotecas y garantizan la compatibilidad binaria con el código escrito para versiones anteriores de esas interfaces.


La nueva característica Java 8 ( Métodos predeterminados ) permite que una interfaz proporcione una implementación cuando se etiqueta con la palabra clave default .

Por ejemplo:

interface Test { default double getAvg(int avg) { return avg; } } class Tester implements Test{ //compiles just fine }

La Prueba de interfaz utiliza la palabra clave predeterminada que permite que la interfaz proporcione una implementación predeterminada del método sin la necesidad de implementar esos métodos en las clases que usan la interfaz.

Compatibilidad con versiones anteriores: imagine que su interfaz es implementada por cientos de clases, modificando esa interfaz obligará a todos los usuarios a implementar el método recién agregado, aunque no es esencial para muchas otras clases que implementan su interfaz.

Hechos y restricciones:

1-Solo se puede declarar dentro de una interfaz y no dentro de una clase o clase abstracta.

2-Debe proporcionar un cuerpo

3-No se supone que sea público o abstracto como otros métodos normales utilizados en una interfaz.


Los métodos predeterminados en una interfaz nos permiten agregar nuevas funcionalidades sin romper el código antiguo.

Antes de Java 8, si se agregaba un nuevo método a una interfaz, entonces todas las clases de implementación de esa interfaz estaban destinadas a anular ese nuevo método, incluso si no usaban la nueva funcionalidad.

Con Java 8, podemos agregar la implementación predeterminada para el nuevo método utilizando la palabra clave default antes de la implementación del método.

Incluso con clases anónimas o interfaces funcionales, si vemos que algún código es reutilizable y no queremos definir la misma lógica en todas partes del código, podemos escribir implementaciones predeterminadas de esos y reutilizarlos.

Ejemplo

public interface YourInterface { public void doSomeWork(); //A default method in the interface created using "default" keyword default public void doSomeOtherWork(){ System.out.println("DoSomeOtherWork implementation in the interface"); } } class SimpleInterfaceImpl implements YourInterface{ /* * Not required to override to provide an implementation * for doSomeOtherWork. */ @Override public void doSomeWork() { System.out.println("Do Some Work implementation in the class"); } /* * Main method */ public static void main(String[] args) { SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl(); simpObj.doSomeWork(); simpObj.doSomeOtherWork(); } }


Los métodos predeterminados le permiten agregar nuevas funcionalidades a las interfaces de sus aplicaciones. También se puede usar para tener una herencia múltiple . Además de los métodos predeterminados, puede definir métodos estáticos en las interfaces. Esto facilita la organización de los métodos auxiliares.


Los métodos predeterminados se agregaron a Java 8 principalmente para admitir expresiones lambda. Los diseñadores (inteligentemente, en mi opinión) decidieron hacer la sintaxis lambdas para crear implementaciones anónimas de una interfaz. Pero dado que las lambdas solo pueden implementar un método único, se limitarían a las interfaces con un método único, lo que sería una restricción bastante severa. En cambio, se agregaron métodos predeterminados para permitir el uso de interfaces más complejas.

Si necesita algo convincente de la afirmación de que el default se introdujo debido a las lambdas, tenga en cuenta que la propuesta del hombre de paja del Proyecto Lambda, de Mark Reinhold, en 2009, menciona los ''Métodos de extensión'' como una característica obligatoria que se debe agregar para admitir lambdas.

Aquí hay un ejemplo que demuestra el concepto:

interface Operator { int operate(int n); default int inverse(int n) { return -operate(n); } } public int applyInverse(int n, Operator operator) { return operator.inverse(n); } applyInverse(3, n -> n * n + 7);

Muy ingenioso, me doy cuenta, pero debería ilustrar cómo default soporta lambdas. Debido a que inverse es un valor predeterminado, una clase de implementación puede anularlo fácilmente si es necesario.


Se introduce un nuevo concepto en Java 8 llamado métodos predeterminados. Los métodos predeterminados son aquellos que tienen una implementación predeterminada y ayudan a evolucionar las interfaces sin romper el código existente. Veamos un ejemplo:

public interface SimpleInterface { public void doSomeWork(); //A default method in the interface created using "default" keyword default public void doSomeOtherWork(){ System.out.println("DoSomeOtherWork implementation in the interface"); } } class SimpleInterfaceImpl implements SimpleInterface{ @Override public void doSomeWork() { System.out.println("Do Some Work implementation in the class"); } /* * Not required to override to provide an implementation * for doSomeOtherWork. */ public static void main(String[] args) { SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl(); simpObj.doSomeWork(); simpObj.doSomeOtherWork(); } }

y la salida es:

Implementar algo de trabajo en la clase
Implementación DoSomeOtherWork en la interfaz