2010-03-02 28 views
9

, bu bir dış sınıfın bir örneği ile ilişkilidir. Merakla, iç sınıfı bir dış sınıfın başka bir örneği ile ilişkilendirmek mümkün mü?Java'da bir iç sınıfın dış sınıf örneğini değiştirmek mümkün mü? bir iç sınıfı örneği oluşturulduğunda Java'da

+0

gelecek Karartılmış java yarışmalarda potansiyel var, ne anlamı var? Biliyorsunuz ki, eğer bir ebeveyn sınıfından ayrılabilir bir iç sınıf istiyorsanız, onu sadece statik olarak ilan edebilirsiniz, değil mi? –

+0

Bu sorunu büyüleyici buluyorum. JLS'de, dış sınıfa işaretçinin nasıl isimlendirildiğini bilen biri var mı? Deneme yoluyla, '$ 0' gibi görünen, gerektiği kadar '$' eklenerek (muhtemelen hiçbiri) görünmüyor. Bu aslında belirtiliyor mu? – polygenelubricants

+0

Tamam Daha yeni bir seviye iç sınıfın bunun yerine $ 1 $ kullandığını öğrendim. Büyüleyici! – polygenelubricants

cevap

6

Evet, bu mümkün, bana gerçekten kötü bir fikir gibi geliyor olsa da. Buradaki fikir, aksi takdirde final işaretçisini yansımayı kullanarak (başarılı olması garanti edilmez) dış örneğe ayarlamaktır.

import java.lang.reflect.*; 

public class Me { 
    final String name; 

    Me(String name) { 
     this.name = name; 
    } 

    class InnerMe {  
     String whoAreYou() { 
      return name; 
     } 
    } 

    InnerMe innerSelf() { 
     return new InnerMe(); 
    } 

    public static void main(String args[]) throws Exception { 
     final Me me = new Me("Just the old me!"); 
     final InnerMe innerMe = me.innerSelf(); 
     System.out.println(innerMe.whoAreYou()); // "Just the old me!" 
     Field outerThis = innerMe.getClass().getDeclaredFields()[0]; 
     outerThis.setAccessible(true); 
     outerThis.set(innerMe, new Me("New and improved me!")); 
     System.out.println(innerMe.whoAreYou()); // "New and improved me!" 
    } 

} 

burada çok önemli bir parçasıdır outerThis.setAccessible(true); - bir SecurityManager başarı bu yasaklayan bir politikayı zorunlu olabilir. Kenara ondan

4

Sen yansıma kullanarak, mümkün olmalıdır.

Sadece iç sınıfı (getClass().getDeclaredFields()) tüm alanlarını almak ve saha ebeveyn tutan bkz sonra (field.set(innerInstance, newParent) kullanmadan önce erişilebilir alanını yapmak gerektiğini söyledi. - setAccessible(true)) ile ayarlama alan görünmektedir yana

final olmak, bunu aşmak için nasıl olduğunu görmek için this article bir göz sürebilir.

sen hiç bunu yapmak gerekmez, dedi ki - bu hiçbir gerçek kazanç için bir çift çirkin kesmek olacaktır. Dış sınıfın diğer örneği ile iç sınıfın mevcut örneğini ilişkilendirmek, o ( setAccessible(true) olmadan) mümkün değildir Ancak

public class Outer { 
    public class Inner {} 
} 
... 
Outer o = new Outer(); 
Outer.Inner i = o.new Inner(); 

: Eğer örnekleme süresi hakkında konuşan varsa

5

, aşağıdaki sözdizimini kullanarak mümkündür , saha içine örneğine işaret çünkü final geçerli:

javap Outer$Inner 

Compiled from "Outer.java" 
public class Outer$Inner extends java.lang.Object{ 
    final Outer this$0; 
    public Outer$Inner(Outer); 
} 
+0

(+1), final ile iyi nokta. O.new Inner() için – Bozho

+0

+1 - Bugün yeni bir sözdizimi öğrendim. –

İlgili konular