0Pricing
Java Academy · บทเรียน

การอ้างอิงตัวสร้าง

ใช้ ClassName::new เพื่อสร้างอินสแตนซ์ผ่านอินเทอร์เฟซเชิงฟังก์ชัน เช่น Supplier และ Function

การอ้างอิงตัวสร้าง เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

การอ้างอิงคอนสตรักเตอร์คืออะไร

การอ้างอิงคอนสตรักเตอร์ใช้ ClassName::new เพื่อสร้างออบเจ็กต์ผ่านอินเทอร์เฟซเชิงฟังก์ชัน พารามิเตอร์ของอินเทอร์เฟซเชิงฟังก์ชันต้องตรงกับพารามิเตอร์ของคอนสตรักเตอร์

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)

คอนสตรักเตอร์ไม่มีอาร์กิวเมนต์ในฐานะ Supplier

คอนสตรักเตอร์ที่ไม่มีอาร์กิวเมนต์ตรงกับ 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); // 0

คอนสตรักเตอร์สองอาร์กิวเมนต์ในฐานะ BiFunction

คอนสตรักเตอร์ที่มีสองพารามิเตอร์ตรงกับ 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]

การอ้างอิงคอนสตรักเตอร์ใน Stream.map

แปลงสตริงเป็นออบเจ็กต์โดยใช้การอ้างอิงคอนสตรักเตอร์:

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)

การอ้างอิงคอนสตรักเตอร์อาร์เรย์

สร้างอาร์เรย์แบบไดนามิกด้วย Type[]::new ซึ่งใช้โดย 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);

รูปแบบอินเทอร์เฟซ Factory

กำหนดอินเทอร์เฟซเชิงฟังก์ชันที่กำหนดเองสำหรับ Factory แล้วใช้การอ้างอิงคอนสตรักเตอร์:

@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);

การแทรกการพึ่งพาด้วยการอ้างอิงคอนสตรักเตอร์

เฟรมเวิร์กมักใช้ Factory เชิงฟังก์ชันเพื่อสร้างอินสแตนซ์เมื่อจำเป็น การอ้างอิงคอนสตรักเตอร์ทำให้รูปแบบนี้เขียนได้อย่างกระชับ:

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");

การเลือกระหว่างแลมบ์ดากับการอ้างอิงคอนสตรักเตอร์

ใช้การอ้างอิงคอนสตรักเตอร์เมื่อเนื้อหาของแลมบ์ดามีเพียง 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());

ชนิดข้อมูลทั่วไปและการอ้างอิงคอนสตรักเตอร์

คลาสชนิดข้อมูลทั่วไปก็ใช้งานได้เช่นกัน — ชนิดข้อมูลจะถูกอนุมานจากบริบทของอินเทอร์เฟซเชิงฟังก์ชัน:

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

ตัวรวบรวมของสตรีมโดยใช้การอ้างอิงคอนสตรักเตอร์

ใช้การอ้างอิงคอนสตรักเตอร์ในตัวรวบรวมเพื่อสร้างคอนเทนเนอร์ผลลัพธ์ที่กำหนดเอง:

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

ชนิดข้อมูลพื้นฐานและการแปลงชนิดอัตโนมัติ

การอ้างอิงคอนสตรักเตอร์สำหรับชนิดข้อมูลห่อหุ้มจะจัดการการแปลงชนิดอัตโนมัติ:

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

ตรวจสอบความเข้าใจอย่างรวดเร็ว

การอ้างอิงคอนสตรักเตอร์ที่ไม่มีอาร์กิวเมนต์ เช่น ArrayList::new ตรงกับอินเทอร์เฟซเชิงฟังก์ชันใด

ทบทวน: การอ้างอิงคอนสตรักเตอร์

ประเด็นสำคัญ:

  • ไวยากรณ์: ClassName::new — มอบหมายให้คอนสตรักเตอร์ที่ตรงกัน
  • ไม่มีอาร์กิวเมนต์ → Supplier<T>; หนึ่งอาร์กิวเมนต์ → Function<T,R>; สองอาร์กิวเมนต์ → BiFunction
  • คอนสตรักเตอร์อาร์เรย์: Type[]::new — ใช้ร่วมกับ Stream.toArray()
  • กระชับกว่าแลมบ์ดาเมื่อเนื้อหาของแลมบ์ดามีเพียง 'new Type(args)'
  • ใช้ Collectors.toCollection(LinkedList::new) สำหรับผลลัพธ์คอลเลกชันที่ระบุชนิดข้อมูล

คำถามที่พบบ่อย

บทเรียน “การอ้างอิงตัวสร้าง” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การอ้างอิงตัวสร้าง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การอ้างอิงตัวสร้าง”

ใช้ ClassName::new เพื่อสร้างอินสแตนซ์ผ่านอินเทอร์เฟซเชิงฟังก์ชัน เช่น Supplier และ Function คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การอ้างอิงตัวสร้าง” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม

ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การอ้างอิงเมธอดแบบ Static
  2. การอ้างอิงเมธอดอินสแตนซ์บนอินสแตนซ์เฉพาะ
  3. การอ้างอิงเมธอดของอินสแตนซ์ใดก็ได้
  4. การอ้างอิงตัวสร้าง
← กลับไปที่ Java Academy