2016-12-07 29 views
15

Znalazłem adnotację @JvmSynthetic w kotlin-stdlib i zastanawiam się, do czego to służy, ale, niestety, jest to nieudokumentowane.Jakie jest przeznaczenie @JvmSynthetic w Kotlin?

O ile rozumiem, zastosowanie go do elementu programu doda modyfikator synthetic do odpowiednich elementów kodu bajtowego. W konsekwencji, element staje się niewidoczny z Java:

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

Gdzieś w kodzie Java:

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

Ale te same elementy są nadal widoczne w kodzie Kotlin:

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

ukrywa deklaracje ze źródeł innych niż kotlin ważne użycie @JvmSynthetic? Czy to jest zamierzone użycie? Jakie są inne odpowiednie przypadki użycia?

Od @JvmSynthetic ukrywa funkcje z Jawy, nie mogą one zostać zastąpione w Javie albo (a jeśli chodzi o człon abstract, rozmowy następnie doprowadzić do AbstractMethodError). Biorąc pod uwagę to, czy mogę użyć @JvmSynthetic, aby zabronić nadpisywania członków klasy Kotlin w źródłach Java?

Odpowiedz

9

W prostym Java, synthetic metody są generowane przez kompilator javac. Zwykle kompilator musi tworzyć metody syntetyczne w klasach zagnieżdżonych, gdy pola określone za pomocą prywatnego modyfikatora są dostępne dla klasy otaczającej.

Biorąc pod uwagę następujące klasy w Javie:

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!"; 
    } 
} 

gdy klasa SyntheticSample dostęp pole nested.syntheticString, to rzeczywiście jest wywołanie statycznej synthetic metodę wygenerowany przez kompilator (o nazwie coś jak access$100).

Nawet jeśli Kotlin ujawnia adnotację @JvmSynthetic, która jest w stanie "wymusić" tworzenie metod syntetycznych, radzę nie używać jej w normalnym kodzie "użytkownika". Metody syntetyczne są sztuczkami niskiego poziomu stworzonymi przez kompilator i nigdy nie powinniśmy polegać na takich rzeczach w codziennym kodzie. Myślę, że jest tam, aby obsługiwać inne części standardowej biblioteki, ale powinieneś zapytać bezpośrednio facetów JetBrains, jeśli jesteś ciekawy (spróbuj oficjalnie Kotlin Discussion Forum)

+1

Zgadzam się, że wygląda to jak niebezpieczne narzędzie, które wymaga ostrożnej obsługi , ale nadal jest częścią 'kotlin-stdlib', jest to publiczny interfejs API. Daje mi do myślenia, że ​​powinny być przypadki użycia '@ JvmSynthetic', które może napotkać zwykły programista (lub może programista bibliotek/narzędzi). Ponadto, 'syntetyczne' metody są używane szersze przez' javac', a następnie tylko dla zagnieżdżonych klas: przynajmniej dla nadpisania metody z innym sygnaturą (włączając ogólne metody nadpisane nietypowymi). – hotkey