Referências a Métodos de Instância Arbitrária
Referencie um método de instância sem especificar o receptor — um recurso muito usado com operações de Stream.
Referências a Métodos de Instância Arbitrária é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.
O que São Referências de Instância Arbitrária?
Uma referência de método de instância arbitrária usa ClassName::instanceMethod. Nesse caso, o primeiro argumento da interface funcional atua como receptor — cada elemento se torna o objeto no qual o método é chamado.
import java.util.*;
import java.util.stream.*;
List<String> names = List.of("alice","bob","carol");
// String::toUpperCase — receiver is each list element
List<String> upper = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(upper); // [ALICE, BOB, CAROL]Como o Receptor é Resolvido
Para uma referência de instância arbitrária Type::method, o primeiro parâmetro da interface funcional se torna this (o receptor):
// String::length matches Function<String, Integer>
// Equivalent to: s -> s.length()
Function<String, Integer> len = String::length;
System.out.println(len.apply("Java")); // 4
// String::isEmpty matches Predicate<String>
// Equivalent to: s -> s.isEmpty()
Predicate<String> isEmpty = String::isEmpty;
System.out.println(isEmpty.test("")); // trueUso Intenso com Operações de Fluxo
As referências de instância arbitrária são o tipo mais comum em cadeias de fluxo:
List<String> words = List.of("Hello","","World","","Java");
// filter with String::isEmpty
long empty = words.stream().filter(String::isEmpty).count();
System.out.println(empty); // 2
// map with String::toLowerCase
words.stream()
.filter(s -> !s.isEmpty())
.map(String::toLowerCase)
.forEach(System.out::println);Estilo BiFunction com Métodos de Dois Argumentos
Um método com dois argumentos em um tipo corresponde a BiFunction<T, U, R>, em que T é o receptor e U é o argumento:
import java.util.function.*;
// String::startsWith → BiPredicate<String, String>
// receiver=first arg, argument=second arg
BiPredicate<String, String> starts = String::startsWith;
System.out.println(starts.test("JavaStream", "Java")); // true
System.out.println(starts.test("Python", "Java")); // falseComparador com Instância Arbitrária
String::compareTo corresponde a Comparator<String> — os dois argumentos do comparador se tornam o receptor e o parâmetro:
List<String> words = List.of("banana","apple","cherry");
List<String> sorted = words.stream()
.sorted(String::compareTo)
.collect(Collectors.toList());
System.out.println(sorted); // [apple, banana, cherry]Instância Arbitrária de uma Classe Personalizada
Funciona com métodos de instância de qualquer classe, não apenas com tipos do JDK:
record Product(String name, double price) {
boolean isExpensive() { return price > 50; }
String label() { return name + " ($" + price + ")"; }
}
List<Product> products = List.of(
new Product("Widget", 9.99),
new Product("Gadget", 99.99),
new Product("Donut", 1.50)
);
products.stream()
.filter(Product::isExpensive)
.map(Product::label)
.forEach(System.out::println); // Gadget ($99.99)Diferença em Relação à Instância Específica
A principal diferença:
- Específica:
obj::method— obj é sempre o receptor - Arbitrária:
Type::method— cada elemento É o receptor
String fixed = "prefix";
// Specific instance: fixed is always the receiver
Predicate<String> startsFixed = fixed::startsWith; // always checks 'prefix'.startsWith(arg)
// Arbitrary instance: each element is the receiver
Predicate<String> isEmpty = String::isEmpty; // each element.isEmpty()Referências de Método em Coletores
As referências de instância arbitrária combinam naturalmente com coletores:
List<String> items = List.of(" hello "," world "," java ");
List<String> trimmed = items.stream()
.map(String::trim)
.collect(Collectors.toList());
System.out.println(trimmed); // [hello, world, java]Encadeando Referências de Método
As referências de método podem ser encadeadas com andThen/compose em Function:
Function<String, String> pipeline =
((Function<String, String>) String::trim)
.andThen(String::toUpperCase);
System.out.println(pipeline.apply(" hello world "));
// HELLO WORLDArmadilha: Métodos Sobrecarregados
Quando um método é sobrecarregado, o compilador precisa inferir qual sobrecarga corresponde à interface funcional. Se houver ambiguidade, ocorrerá um erro de compilação — use uma expressão lambda para desambiguar:
// println is overloaded — which one?
// Consumer<String> c = System.out::println; // OK — infers println(String)
// Consumer<Object> c2 = System.out::println; // OK
// But if ambiguous:
// Function<Object,?> fn = System.out::println; // Error — println doesn't return a valueDesempenho
Referências de método e expressões lambda são compiladas para o mesmo código de bytes por meio de uma chamada dinâmica. Não há diferença de desempenho — escolha a opção mais legível. A maioria dos guias de estilo prefere referências de método quando elas expressam a intenção de forma clara.
Verificação Rápida
O que String::toUpperCase representa quando usado com .map()?
Recapitulação: Referências de Método de Instância Arbitrária
Principais conclusões:
- Sintaxe: ClassName::instanceMethod — cada elemento é o receptor
- Corresponde a interfaces funcionais nas quais o receptor é o primeiro parâmetro
- Mais comum em .map(), .filter(), .sorted() e .forEach()
- Métodos com dois argumentos → BiFunction/BiPredicate, com o elemento como receptor
- Nenhuma diferença de desempenho em relação à expressão lambda — escolha pela legibilidade
Perguntas Frequentes
A aula “Referências a Métodos de Instância Arbitrária” é grátis?
Sim — o texto completo de “Referências a Métodos de Instância Arbitrária” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.
O que vou aprender em “Referências a Métodos de Instância Arbitrária”?
Referencie um método de instância sem especificar o receptor — um recurso muito usado com operações de Stream. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Java Academy?
Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Referências a Métodos de Instância Arbitrária”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Java Academy?
Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Referências a Métodos Estáticos
- Referências a Métodos de Instância Específica
- Referências a Métodos de Instância Arbitrária
- Referências a Construtores