Técnico

Java8: Modificador de acesso DEFAULT

A maioria dos desenvolvedores perceberam grandes mudanças em diversas APIs do Java 8, como adições de métodos em interfaces como sort(), foreach() e outros na interface List ou Stream, essa modificação só foi possível com a modificação do bytecode rodado na JVM, possibilitando a criação de um novo tipo modicador de acesso chamado default.

Um dos grandes problemas sempre foi a adição de novos métodos em interfaces antigas que necessitam de atualização como por exemplo a API de Collections, um novo método em uma interface torna a implementação necessária em todas as classes que implementam, assim quebrando a compatibilidade com versões anteriores da linguagem, dado a restrição a API de Collections foi criada na versão 1.2 em 1998 e ficou 20 anos sem nenhuma modificação.

Esse modificador chamado de default foi criado com a finalidade de criar métodos em interfaces sem quebrar o contrato com classes existentes, uma peculiaridade é que esses métodos necessitam a criação de um de um comportamento padrão, e por isso são chamados de métodos padrão (default methods).

Vemos o método adicionado ao código na interface List, chamado .sort(), a necessidade veio de não ser mais necessário ter que chamar uma classe utilitária externa.

[cc lang=”java” tab_size=”2″ theme=”blackboard” noborder=”true” line_numbers=”false”]

@SuppressWarnings({“unchecked”, “rawtypes”})
default void sort(Comparator c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}

[/cc]

Vamos implementar uma classe de teste para entender os conceitos e comportamentos a feature.

[cc lang=”java” tab_size=”2″ theme=”blackboard” noborder=”true” line_numbers=”false”]

package io.redspark.java8.modifierdefault;

import org.junit.Assert;
import org.junit.Test;

public class DefaultModifierTest {

public interface Fighter {
default String fight() {
return “Fight with knife”;
}
}

public interface BasicFighter {
default String fight(){
return “Fight with hand”;
}
}

public class HumanFighter implements Fighter {}
public class GlobinFighter implements Fighter {
@Override
public String fight() {
return “Fight with axe”;
}
}

/**
* default access enable implement methods without obligatoriness and must have a default behavior.
*/
@Test
public void testDefaultMethodWithBehavior() throws Exception {

HumanFighter humanFighter = new HumanFighter();
Assert.assertEquals(“Fight with knife”, humanFighter.fight());

GlobinFighter globinFighter = new GlobinFighter();
Assert.assertEquals(“Fight with axe”, globinFighter.fight());
}

}

[/cc]

A criação de métodos com comportamento padrão evita outro problema na modelagem de objetos, uso indiscriminado de herança, esse novo tipo de contrato garante que humanos e globins lutem com um comportamento padrão, sem a necessidade de estender uma classe abstrata por exemplo.

Suporte a multiplas intefaces

Todo o comportamento padrão de interfaces é mantido, como vimos GlobinFighter simplesmente sobrescreve o método com o comportamento de um globin, assim como podemos usar múltiplas interfaces, mas nesse caso é necessário na classe concreta.

[cc lang=”java” tab_size=”2″ theme=”blackboard” noborder=”true” line_numbers=”false”]

package io.redspark.java8.modifierdefault;

import org.junit.Assert;
import org.junit.Test;

public class DefaultModifierTest {

public interface Fighter {
default String fight() {
return “Fight with knife”;
}
}

public interface BasicFighter {
default String fight(){
return “Fight with hand”;
}
}

public class HumanFighter implements Fighter {}

public class PoorFighter implements BasicFighter, Fighter {
@Override
public String fight() {
return BasicFighter.super.fight();
}
}

@Test
public void testCreateClassWithMultipleInterfaceAndUsingSameNameOfDefaultMethod() throws Exception {

PoorFighter poorFighter = new PoorFighter();
Assert.assertEquals(“Fight with hand”, poorFighter.fight());
}
}

[/cc]

Os exemplos completos podem ser conferidos nesse repositório no Github.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Compartilhe isso: