0Pricing
Java Academy · Aula

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(""));   // true

Uso 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"));      // false

Comparador 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 WORLD

Armadilha: 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 value

Desempenho

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

  1. Referências a Métodos Estáticos
  2. Referências a Métodos de Instância Específica
  3. Referências a Métodos de Instância Arbitrária
  4. Referências a Construtores
← Voltar para Java Academy