Références vers des méthodes d’instance arbitraires
Référencez une méthode d’instance sans préciser le récepteur — une technique très utilisée avec les opérations sur les flux.
Références vers des méthodes d’instance arbitraires est une leçon Java Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Java Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Java Academy comprend 4 leçons au total.
Que sont les références sur une instance arbitraire ?
Une référence de méthode sur une instance arbitraire utilise ClassName::instanceMethod. Ici, le premier argument de l'interface fonctionnelle sert de récepteur : chaque élément devient l'objet sur lequel la méthode est appelée.
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]Comment le récepteur est déterminé
Pour une référence sur une instance arbitraire Type::method, le premier paramètre de l'interface fonctionnelle devient this (le récepteur) :
// 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("")); // trueUtilisation intensive avec les opérations sur les flux
Les références sur une instance arbitraire sont le type le plus courant dans les pipelines de flux :
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);Style BiFunction avec des méthodes à deux arguments
Une méthode à deux arguments sur un type correspond à BiFunction<T, U, R>, où T est le récepteur et U l'argument :
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")); // falseComparator avec une instance arbitraire
String::compareTo correspond à Comparator<String> — les deux arguments du comparateur deviennent le récepteur et le paramètre :
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]Instance arbitraire avec une classe personnalisée
Cela fonctionne avec les méthodes d'instance de n'importe quelle classe, et pas seulement avec les types du 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)Différence avec une instance spécifique
La différence essentielle :
- Spécifique :
obj::method— obj est toujours le récepteur - Arbitraire :
Type::method— chaque élément EST le récepteur
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()Références de méthode dans les collecteurs
Les références sur une instance arbitraire se combinent naturellement avec les collecteurs :
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]Chaînage de références de méthode
Les références de méthode peuvent être chaînées avec andThen/la composition sur Function :
Function<String, String> pipeline =
((Function<String, String>) String::trim)
.andThen(String::toUpperCase);
System.out.println(pipeline.apply(" hello world "));
// HELLO WORLDPiège : méthodes surchargées
Lorsqu'une méthode est surchargée, le compilateur doit déterminer quelle surcharge correspond à l'interface fonctionnelle. En cas d'ambiguïté, une erreur de compilation se produit — utilisez une lambda pour lever l'ambiguïté :
// 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 valuePerformances
Les références de méthode et les lambdas sont compilées en même bytecode (via invokedynamic). Il n'y a aucune différence de performances : choisissez la forme la plus lisible. La plupart des guides de style préfèrent les références de méthode lorsqu'elles expriment clairement l'intention.
Vérification rapide
Que représente String::toUpperCase lorsqu'il est utilisé avec .map() ?
Récapitulatif : références de méthode sur une instance arbitraire
Points essentiels :
- Syntaxe : ClassName::instanceMethod — chaque élément est le récepteur
- Correspond aux interfaces fonctionnelles dont le premier paramètre est le récepteur
- Très courant dans .map(), .filter(), .sorted() et .forEach()
- Les méthodes à deux arguments donnent BiFunction/BiPredicate, avec l'élément comme récepteur
- Aucune différence de performances par rapport à une lambda — choisissez selon la lisibilité
Questions Fréquemment Posées
La leçon « Références vers des méthodes d’instance arbitraires » est-elle gratuite ?
Oui — le texte complet de « Références vers des méthodes d’instance arbitraires » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Java Academy, passe à CoddyKit PRO. Le cours Java Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Références vers des méthodes d’instance arbitraires » ?
Référencez une méthode d’instance sans préciser le récepteur — une technique très utilisée avec les opérations sur les flux. Tu pratiques Java Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Java Academy ?
Aucune expérience préalable n'est requise. Java Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.
Combien de temps prend la leçon « Références vers des méthodes d’instance arbitraires » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Java Academy ?
Oui. Chaque leçon Java Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Références vers des méthodes statiques
- Références vers des méthodes d’instance précises
- Références vers des méthodes d’instance arbitraires
- Références vers des constructeurs