Câu hỏi Mục đích sử dụng của @JvmSynthetic trong Kotlin là gì?


Tôi đã đi qua @JvmSynthetic chú thích trong kotlin-stdlib, và tôi tự hỏi nó là cái gì, nhưng, thật không may, nó không có giấy tờ.

Theo như tôi hiểu, việc áp dụng nó vào phần tử chương trình sẽ thêm synthetic sửa đổi thành các phần tử bytecode tương ứng. Kết quả là, phần tử trở thành vô hình từ Java:

class MyClass {
    @JvmSynthetic
    fun f() { }
}

Một nơi nào đó trong mã Java:

MyClass c = new MyClass();
c.f() // Error: cannot resolve method f()

Nhưng các yếu tố tương tự vẫn hiển thị trong mã Kotlin:

val c = MyClass()
c.f() // OK

Ẩn các khai báo từ các nguồn không phải Kotlin, sử dụng hợp lệ @JvmSynthetic? Đó có phải là mục đích sử dụng không? Các trường hợp sử dụng thích hợp khác là gì?

@JvmSynthetic ẩn các chức năng từ Java, chúng không thể bị ghi đè trong Java (và khi nói đến một abstract thành viên, các cuộc gọi sau đó kết quả thành AbstractMethodError). Cho rằng, tôi có thể sử dụng @JvmSynthetic thế nào để ngăn cấm các thành viên của một lớp Kotlin trong các nguồn Java?


15
2017-12-07 16:15


gốc


Tôi sử dụng nó để ẩn các khai báo từ Java, đặc biệt là cho các khai báo @PublishedApi internal, i. e. có thể truy cập trong các hàm nội tuyến. - Miha_x64


Các câu trả lời:


Trong Java đơn giản, synthetic các phương thức được tạo bởi javac trình biên dịch. Thông thường trình biên dịch phải tạo các phương thức tổng hợp trên các lớp lồng nhau, khi các trường được chỉ định với bộ sửa đổi riêng được truy cập bởi lớp kèm theo.

Cho lớp sau trong java:

public final class SyntheticSample
{
    public static void main(final String[] args)
    {
        SyntheticSample.Nested nested = new SyntheticSample.Nested();
        out.println("String: " + nested.syntheticString);
    }

    private static final class Nested
    {
        private String syntheticString = "I'll become a method!";
    }
}

khi mà SyntheticSample lớp truy cập nested.syntheticString trường, nó thực sự gọi là tĩnh synthetic phương thức được tạo bởi trình biên dịch (được đặt tên giống như access$100).

Ngay cả khi Kotlin phơi bày một @JvmSynthetic chú thích có thể "ép buộc" việc tạo ra các phương thức tổng hợp, tôi khuyên không nên sử dụng nó trong mã "người dùng" bình thường. Các phương thức tổng hợp là các thủ thuật cấp thấp được trình biên dịch tạo ra, và chúng ta không bao giờ nên dựa vào những thứ như vậy trong mã hàng ngày. Tôi nghĩ rằng nó ở đó để hỗ trợ các phần khác của thư viện chuẩn, nhưng bạn nên hỏi trực tiếp những người chơi JetBrains nếu bạn tò mò Diễn đàn thảo luận Kotlin)


10
2017-12-07 18:53



Vâng, tôi đồng ý nó trông giống như một công cụ nguy hiểm cần xử lý cẩn thận, nhưng nó vẫn là một phần của kotlin-stdlib, đó là API công khai. Nó làm cho tôi nghĩ rằng nên có trường hợp sử dụng cho @JvmSynthetic mà một nhà phát triển bình thường (hoặc có thể là một nhà phát triển thư viện / công cụ) có thể gặp phải. Cũng thế, synthetic phương pháp được sử dụng rộng hơn bởi javac sau đó chỉ dành cho các lớp lồng nhau: ít nhất là để ghi đè một phương thức có chữ ký khác (bao gồm cả các phương thức chung chung được ghi đè với các lớp không chung chung). - hotkey