Java'da Sentetik Sınıf


143

Java'da sentetik sınıf nedir? Neden kullanılmalı? Nasıl Kullanabilirim?


1
Lambdalar sentetik (anonim değil) olarak uygulanabileceğinden, "kodunuzda değil" yanıtlarının tümü Java 8 ile güncel değildir.
OrangeDog

Adil olmak gerekirse, bir lambda hala kodunuz içinde açıkça tanımlanmış bir sınıf değildir. Dolayısıyla, "kodunuzda değil" hala geçerlidir. Derleyici, kodunuzda açık bir tanım olmadan sizin için sentetik sınıflar oluşturur.
ManoDestra

Yanıtlar:


15

Örneğin, bir switch deyiminiz olduğunda java, $ ile başlayan bir değişken oluşturur. Bunun bir örneğini görmek istiyorsanız, içinde bir anahtar deyimi olan bir sınıfın java yansımasına bakın. Sınıfın herhangi bir yerinde en az bir switch deyiminiz olduğunda bu değişkenleri göreceksiniz.

Sorunuzu cevaplamak için, sentetik sınıflara erişebildiğinize (yansıma dışında) inanmıyorum.

Hakkında bir şey bilmediğiniz (yansıma yoluyla) bir sınıfı analiz ediyorsanız ve o sınıf hakkında çok özel ve düşük düzeyli şeyler bilmeniz gerekiyorsa, sentetik sınıflarla ilgili olan Java yansıma yöntemlerini kullanabilirsiniz. Buradaki tek "kullanım", kodunuzda uygun şekilde kullanabilmek için sınıf hakkında daha fazla bilgi edinmektir.

(Bunu yapıyorsanız, muhtemelen diğer geliştiricilerin kullanabileceği bazı türlerden bir çerçeve oluşturuyorsunuz.)

Aksi takdirde, yansıma kullanmıyorsanız, bildiğim sentetik sınıfların pratik kullanımları yoktur.


1
Evet, bir örnek verebilirseniz örnek kod iyi olur /
nanofarad

36
Bu soruya cevap vermiyor.
Dawood ibn Kareem

Anahtar durumu için, bunun her anahtar için olup olmadığından emin değilim, ancak bunu enum'lu anahtar için gözlemledim; derleyici, bir Enum.ordinal () -> 1, 2, 3 ... (böylece boşluklar olmadan bir dizi) eşlemesi sağlayan tek bir statik alanla anonim bir sınıf oluşturur ve daha sonra bir lookupswitch komutu, anahtarı doğrudan değil, bu sekans üzerinde çalıştırır. sıralarda.
Radim Vansa

106

Java, çalışma zamanında sınıflar oluşturma yeteneğine sahiptir. Bu sınıflar Sentetik Sınıflar veya Dinamik Proxy'ler olarak bilinir.

Daha fazla bilgi için http://java.sun.com/j2se/1.5.0/docs/guide/reflection/proxy.html adresine bakın .

CGLIB ve ASM gibi diğer açık kaynaklı kütüphaneler de sentetik sınıflar oluşturmanıza izin verir ve JRE ile sağlanan kütüphanelerden daha güçlüdür.

Sentetik sınıflar, Spring AOP ve AspectJ gibi AOP (Aspect Oriented Programming) kütüphaneleri ve Hibernate gibi ORM kütüphaneleri tarafından kullanılır.


6
Dinamik Proxy'ler Sentetik Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[]{Runnable.class}, (proxy, method, args1) -> null).getClass().isSynthetic() == false
Sınıflar

3
İçin javadoc java.lang.reflect.Member#isSyntheticdiyor ki: Bu üye derleyici tarafından tanıtıldıysa true değerini döndürür; aksi takdirde yanlış döndürür.
Guillaume Husta

Javadoc'un java.lang.reflect.Member#isSyntheticasıl soru ile alakasız olduğuna inanıyorum . Üyeler alanlar, kurucular ve yöntemlerdir. Orijinal soru sentetik üyelerle değil, sentetik sınıflarla ilgiliydi . Java 8'de lambda ifadeleri sentetik sınıflara yol açar - başka hangi koşulların ortaya çıkabileceğinden emin değilim.
Fr Jeremy Krieg

54

Ben Google'da ilk sorunun cevabını buldum:

Sınıf derleyici tarafından oluşturulmuşsa sentetik olarak işaretlenebilir, yani kaynak kodunda görünmez.

Bu sadece temel bir tanım ama bir forum iş parçacığında buldum ve hiçbir açıklama yoktu. Hala daha iyi bir tane arıyorum ...


15

sentetik sınıflar / yöntemler / alanlar:

Bunlar VM için önemlidir. Aşağıdaki kod snippet'ine bir göz atın:

class MyOuter {

  private MyInner inner;

  void createInner() {
    // The Compiler has to create a synthetic method
    // to construct a new MyInner because the constructor
    // is private.
    // --> synthetic "constructor" method
    inner = new MyInner();

    // The Compiler has to create a synthetic method
    // to doSomething on MyInner object because this
    // method is private.
    // --> synthetic "doSomething" method
    inner.doSomething();
  }

  private class MyInner {
    // the inner class holds a syntetic ref_pointer to
    // the outer "parent" class
    // --> synthetic field
    private MyInner() {
    }
    private void doSomething() {
    }
  }
}

2
@CiroSantilli 烏坎 事件 2016 六四 事件 法轮功, hayır, sadece sentetik erişimci yöntemleri.
Miha_x64

8

Bu tartışmaya göre , dil spesifikasyonu sınıflar için bir "isSynthetic" özelliğini tarif etse de, bu uygulamalar tarafından hemen hemen göz ardı edilir ve dinamik proxy'ler veya anonim sınıflar için kullanılmaz. Sentetik alanlar ve yapıcılar iç içe sınıfları uygulamak için kullanılır (bayt kodunda iç içe sınıflar kavramı yoktur, yalnızca kaynak kodunda).

Sentetik sınıflar kavramının yararlı olmadığını kanıtladım, yani hiç kimse bir sınıfın sentetik olup olmadığını umursamıyor. Alanlar ve yöntemler ile muhtemelen tam olarak tek bir yerde kullanılır: IDE sınıfı yapı görünümünde neyin gösterileceğini belirlemek için - normal yöntemlerin ve alanların orada görünmesini istiyorsunuz, ancak iç içe sınıfları simüle etmek için kullanılan sentetik olanları değil. OTOH, anonim sınıfların orada görünmesini istiyorsun.


@OrangeDog: evet, ben de yazdım.
Michael Borgwardt

Java 8 - lambdas ve yöntem referansları bu özelliği kullandığından bu yanıt eski gibi görünüyor. Bunu gösteren bir cevap
Hulk

7

JVM tarafından, iç sınıfın özel üyelerini hata ayıklama amacıyla çağırdıklarında çalışma zamanında oluşturulurlar

JVM tarafından yürütme amacıyla çalışma süresi boyunca oluşturulan yöntemler, alanlar, sınıf Sentetik olarak adlandırılır

http://www.javaworld.com/article/2073578/java-s-synthetic-methods.html

http://javapapers.com/core-java/java-synthetic-class-method-field/


Sanırım derleme zamanında demek istiyorsun, çalışma zamanında değil.
Mostowski Çöküşü

@sathis, JVM değil, javac mı demek istediniz?
Miha_x64

3

Ayrıca EasyMock tarafından Sentetik Sınıflar veya Dinamik Proxy'ler, çalışma zamanında arayüzlerin veya soyut sınıfların uygulamalarını oluşturmak için kullanılır.

http://www.easymock.org/


2

Java derleyicisi iç sınıflar gibi belirli yapıları derlediğinde, sentetik yapılar oluşturur ; bunlar, kaynak kodunda karşılık gelen bir yapıya sahip olmayan sınıflar, yöntemler, alanlar ve diğer yapılardır.
Kullanım Alanları: Sentetik yapılar, Java derleyicilerinin JVM'de değişiklik yapmadan yeni Java dili özelliklerini uygulamasını sağlar. Bununla birlikte, sentetik yapılar farklı Java derleyici uygulamaları arasında değişiklik gösterebilir. Bu, .class dosyalarının farklı uygulamalar arasında da değişebileceği anlamına gelir.
başvuru: docs.oracle.com


2

Çeşitli cevapların daha önce işaret ettiği gibi, derleyicinin doğrudan sos kodundaki bir şeye karşılık gelmeyen çeşitli yapılar (sınıflar dahil) üretmesine izin verilir. Bunlar sentetik olarak işaretlenmelidir:

13.1. İkili Form

Bir sınıf veya arabirim için ikili gösterim de aşağıdakilerin tümünü içermelidir:
[...]
11. Java derleyicisi tarafından yayılan bir yapı, kaynak kodunda açıkça veya örtülü olarak bildirilen bir yapıya karşılık gelmiyorsa, sentetik olarak işaretlenmelidir. , yayılan yapı bir sınıf başlatma yöntemi değilse (JVMS §2.9).
[...]

@Holger tarafından başka bir soruya yapılan bir yorumda belirtildiği gibi, bu tür yapılara ilişkin örnekler, yöntem referanslarını ve lambdasları temsil eden Sınıf nesneleridir:

System.out.println(((Runnable) System.out::println).getClass().isSynthetic());
System.out.println(((Runnable) () -> {}).getClass().isSynthetic());

Çıktı:

true
true

Bu açıkça belirtilmese de, 15.27.4'ten sonra gelmektedir. Lambda İfadelerinin Çalışma Zamanı Değerlendirmesi :

Lambda ifadesinin değeri, aşağıdaki özelliklere sahip bir sınıf örneğine başvurudır: [...]

ve yöntem referansları için neredeyse özdeş ifadeler ( 15.13.3. Yöntem Referanslarının Çalışma Zamanı Değerlendirmesi ).

Bu sınıf kaynak kodun hiçbir yerinde açıkça belirtilmediği için sentetik olması gerekir.


1

Doğru yaparsam, sentetik bir sınıf, açık bir ad vermek zorunda kalmadan, anında oluşturulmuş bir sınıftır. Örneğin:

//...
Thread myThread = new Thread() {
         public void run() {
           // do something ...
         }
       };
myThread.start();
//...

Bu iş parçacığının sentetik bir alt sınıfını oluşturur ve run () yöntemini geçersiz kılar, sonra başlatır ve başlatır.


3
Ben anonim bir iç sınıf olduğunu düşündüm
Kumar Abhinav

2
@KumarAbhinav ile hemfikirim. Tüm anonim iç sınıflar sentetik değildir. Bkz: xinotes.net/notes/note/1339
bvdb

Anonim iç sınıflar Oracle JDK 1.8.0_45'te sentetik sınıflar oluşturmaz, tür adlarıyla ayrı sentetik olmayan sınıflar oluşturur Outer$1.class.
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功

1

Kodunuzda sentetik bir sınıf görünmüyor: derleyici tarafından oluşturuluyor. Java'da derleyici tarafından yapılan bir köprü yöntemi tipik olarak sentetiktir.

public class Pair<T> {
    private T first;
    private T second;
    public void setSecond(T newValue) {
        second = newValue;
    }
}


public class DateInterval extends Pair<String> {
    public void setSecond(String second) {
        System.out.println("OK sub");
    }

    public static void main(String[] args) throws NoSuchFieldException, SecurityException {
        DateInterval interval = new DateInterval();
        Pair pair = interval;
        pair.setSecond("string1");
    }
}

Komutu kullanarak javap -verbose DateIntervalbir köprü yöntemi görebilirsiniz:

public void setSecond(java.lang.Object);
flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC

Bu derleyici tarafından yapılmıştır; kodunuzda görünmüyor.


1

Java'da sentetik sınıf nedir?

Bir syntheticsınıf bir olduğunu .classtarafından oluşturulan dosya Java derleyicisi ve kaynak kodunda mevcut değil.

syntheticSınıf kullanımı örneği : Anonim iç sınıf

Neden kullanılmalı?

Java derleyici mantığı içinde .classdosyayı oluşturmak için bir mekanizmadır

Nasıl Kullanabilirim?

Hayır, geliştiriciler do DEĞİL doğrudan kullanın.

Java derleyici dosya syntheticoluşturmak için kullanın .classve sonra JVM .classprogram mantığını yürütmek için dosyayı okur .

Daha fazla detay

  • Bu makalesynthetic sınıfı ayrıntılı olarak açıklamaktadır
  • Bu bağlantı , tüm listeler syntheticsınıf çıkışlarını JDK

makale çok yararlıdır, teşekkür ederim
JasonMing

0

Sentetik yapılar, kaynak kodunda karşılık gelen bir yapıya sahip olmayan sınıflar, yöntemler, alanlar vb. Sentetik yapılar, Java derleyicilerinin JVM'de değişiklik yapmadan yeni Java dili özelliklerini uygulamasını sağlar. Bununla birlikte, sentetik yapılar farklı Java derleyici uygulamaları arasında değişiklik gösterebilir. Bu, .class dosyalarının farklı uygulamalar arasında da değişebileceği anlamına gelir.


1
-1. Aynı metin, kelimesi kelimesine, sizden bir yıl önce verilen cevapta yayınlanmıştır [ stackoverflow.com/a/24271953/1144395] ve ayrıca bu cevap, metnin kaynaklandığı resmi referanstan alıntı yaptı ve daha kolay okuma için biçimlendirme sağladı . Lütfen açıkça yinelenen cevapları olan soruları spam göndermeyin.
naki
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.