Odwołania do konstruktorów
Używaj ClassName::new do tworzenia instancji za pośrednictwem interfejsów funkcyjnych, takich jak Supplier i Function.
Odwołania do konstruktorów to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.
Czym są referencje do konstruktorów?
Referencja do konstruktora używa składni ClassName::new do tworzenia obiektów za pośrednictwem interfejsu funkcyjnego. Parametry interfejsu funkcyjnego odpowiadają parametrom konstruktora.
import java.util.function.*;
class Person {
String name;
Person(String name) { this.name = name; }
public String toString() { return "Person(" + name + ")"; }
}
// Function<String, Person> — calls Person(String)
Function<String, Person> factory = Person::new;
Person p = factory.apply("Alice");
System.out.println(p); // Person(Alice)Konstruktor bezargumentowy jako Supplier
Konstruktor bezargumentowy pasuje do Supplier<T>:
class Counter {
int count = 0;
void inc() { count++; }
}
Supplier<Counter> newCounter = Counter::new;
Counter c1 = newCounter.get();
Counter c2 = newCounter.get(); // independent instances
c1.inc();
System.out.println(c1.count); // 1
System.out.println(c2.count); // 0Konstruktor z dwoma argumentami jako BiFunction
Konstruktory z dwoma parametrami pasują do BiFunction<T,U,R>:
record Point(int x, int y) {}
BiFunction<Integer, Integer, Point> makePoint = Point::new;
Point p = makePoint.apply(3, 4);
System.out.println(p); // Point[x=3, y=4]Referencja do konstruktora w Stream.map
Konwertuj napisy na obiekty za pomocą referencji do konstruktora:
import java.util.*;
import java.util.stream.*;
List<String> names = List.of("Alice","Bob","Carol");
List<Person> people = names.stream()
.map(Person::new) // calls new Person(name) for each
.collect(Collectors.toList());
people.forEach(System.out::println);
// Person(Alice)
// Person(Bob)
// Person(Carol)Referencja do konstruktora tablicy
Twórz tablice dynamicznie za pomocą Type[]::new. Jest to używane przez Stream.toArray():
import java.util.stream.*;
String[] arr = Stream.of("a","b","c")
.toArray(String[]::new);
for (String s : arr) System.out.print(s + " ");
// a b c
int[] sizes = {3, 5, 2};
String[][] matrix = Arrays.stream(sizes)
.mapToObj(String[]::new)
.toArray(String[][]::new);Wzorzec interfejsu fabryki
Zdefiniuj własny interfejs funkcyjny dla fabryk, a następnie użyj referencji do konstruktora:
@FunctionalInterface
interface Factory<T> {
T create(String config);
}
class DBConnection {
String url;
DBConnection(String url) { this.url = url; }
public String toString() { return "DB(" + url + ")"; }
}
Factory<DBConnection> dbFactory = DBConnection::new;
DBConnection conn = dbFactory.create("jdbc:postgresql://localhost/mydb");
System.out.println(conn);Wstrzykiwanie zależności za pomocą referencji do konstruktorów
Frameworki często używają funkcyjnych fabryk do leniwego tworzenia instancji. Referencje do konstruktorów sprawiają, że ten wzorzec jest przejrzysty:
import java.util.function.*;
class ServiceLocator {
private final Map<String, Supplier<?>> registry = new HashMap<>();
<T> void register(String name, Supplier<T> factory) {
registry.put(name, factory);
}
@SuppressWarnings("unchecked")
<T> T get(String name) { return (T) registry.get(name).get(); }
}
ServiceLocator loc = new ServiceLocator();
loc.register("counter", Counter::new);
Counter c = loc.get("counter");Wybór między wyrażeniem lambda a referencją do konstruktora
Użyj referencji do konstruktora, gdy ciało wyrażenia lambda zawiera tylko new Type(args):
// Lambda:
Function<String, Person> f1 = name -> new Person(name);
// Constructor reference (preferred):
Function<String, Person> f2 = Person::new;
// When you need extra logic, stick with lambda:
Function<String, Person> f3 = name -> new Person(name.trim().toLowerCase());Typy generyczne i referencje do konstruktorów
Klasy generyczne również działają — typ jest wywnioskowywany z kontekstu interfejsu funkcyjnego:
import java.util.*;
import java.util.function.*;
// ArrayList::new matches Supplier<ArrayList<String>>
Supplier<List<String>> listFactory = ArrayList::new;
List<String> l1 = listFactory.get();
List<String> l2 = listFactory.get(); // independent lists
l1.add("hello");
System.out.println(l2.size()); // 0Kolektory strumieniowe używające referencji do konstruktorów
Używaj referencji do konstruktorów w kolektorach, aby tworzyć własne kontenery wynikowe:
import java.util.stream.*;
// Collect into a LinkedList using a constructor reference supplier
LinkedList<String> linked = Stream.of("a","b","c")
.collect(Collectors.toCollection(LinkedList::new));
System.out.println(linked.getFirst()); // aTypy prymitywne i autoboxing
Referencje do konstruktorów typów opakowujących obsługują autoboxing:
// Integer::new is deprecated in Java 9+, but illustrates the concept
// Use Integer.valueOf or just autoboxing in modern Java
Function<String, Integer> intParser = Integer::parseInt; // static method ref
System.out.println(intParser.apply("42")); // 42Szybkie sprawdzenie
Do jakiego interfejsu funkcyjnego pasuje referencja do konstruktora bezargumentowego, taka jak ArrayList::new?
Podsumowanie: referencje do konstruktorów
Najważniejsze informacje:
- Składnia: ClassName::new — deleguje do pasującego konstruktora
- Bez argumentów → Supplier<T>; jeden argument → Function<T,R>; dwa argumenty → BiFunction
- Konstruktor tablicy: Type[]::new — używany z Stream.toArray()
- Czytelniejsze od wyrażenia lambda, gdy jego ciało zawiera tylko 'new Type(args)'
- Używaj Collectors.toCollection(LinkedList::new) dla wyników kolekcji o określonym typie
Często zadawane pytania
Czy lekcja „Odwołania do konstruktorów” jest bezpłatna?
Tak — pełny tekst „Odwołania do konstruktorów” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Odwołania do konstruktorów”?
Używaj ClassName::new do tworzenia instancji za pośrednictwem interfejsów funkcyjnych, takich jak Supplier i Function. Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Java Academy?
Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Odwołania do konstruktorów”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?
Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Odwołania do metod statycznych
- Odwołania do metod instancji konkretnego obiektu
- Odwołania do metod dowolnej instancji
- Odwołania do konstruktorów