2011-12-09 30 views
9

Tür silme işleminden kaçınmanın ve bir tür parametresine erişmenin bir yolu var mı?Java Türü Silme Durumundan Kaçınma

public class Foo<T extends Enum<?> & Bar> { 
    public Foo() { 
     // access the template class here? 
     // i.e. : 
     baz(T.class); // obviously doesn't work 
    } 

    private void baz(Class<T> qux) { 
     // do stuff like 
     T[] constants = qux.getEnumConstants(); 
     ... 
    } 
} 

Ben yaklaşık T bilmek gerekir, ve onunla şeyler yaparlar. Mümkün mü ve eğer öyleyse, olmadan , yapıcıda veya parametrenin yanı sıra herhangi bir yerde sınıfta geçirmeden nasıl yapılabilir?

DÜZENLEME: Bu sorunun temel amacı tipi silinmeye etrafında herhangi pratik bir yoluolup olmadığını bulmaktır.

cevap

5

AFACT: İşte müstakil bir örnektir. Tabii ki, her bir enum için Bar arayüzünü uygulayan alt sınıf jenerik sınıflarının pratik bir çalışma olduğunu kabul edersiniz.

enum Test implements Bar { 
    ONE, TWO 
} 

class Foo<T> extends FooAbstract<Test> { 
    public Foo() { 
     ParameterizedType genericSuperclass = 
       (ParameterizedType) getClass().getGenericSuperclass(); 
     baz((Class<T>) genericSuperclass.getActualTypeArguments()[0]); 
    } 

    private void baz(Class<T> qux) { 
     T[] constants = qux.getEnumConstants(); 
     System.out.println(Arrays.toString(constants)); // print [ONE, TWO] 
    } 
} 

interface Bar { 
} 

class FooAbstract<T extends Enum<?> & Bar> { 
} 
+2

+1 Evet - Bu, "Sınıf" nesnesini geçmeye alt sınıflamayı tercih ederseniz, yansıma tabanlı başka bir alternatiftir. –

2

bir sınıf yapıcısı jetonu el mümkün/istekli iseniz:

public Foo(Class<T> clazz) { 
    baz(clazz); 
} 

private void baz(Class<T> qux) { 
    // ... 
} 

Bu şekilde, Class.newInstance(), rasgele nesneleri döküm denemesi ile tip T nesneleri üretebilir T Class.cast() kullanarak, vb.

Baz() 'da ne yapmayı düşünüyorsunuz?

+0

Diyelim ki, verilen bir sınıfı değerler listesi için sorar ve bu değerleri kullanır. Sınıfta geçmek yapmak istediğim şey değil. –

1

Anlatımcı, yanıtında dikkat çektiği gibi, bunu başarmanın tek yolu, T türünü temsil eden Class nesnesini geçirmektir.gibi bir şeyin Type Erasure olması mümkün değildir çünkü T çalışma zamanından önce silinmiştir.

Class nesnesinde geçirilmeye karşı dayanıklı görünüyorsunuz, ancak getEnumConstants() yöntemini kullanmanın tek yolu budur. Eğer çalışma zamanı erişimi olmayan bir şeyi isteyemem, çünkü tip silme etrafında pratik bir yolu yoktur,

public class Foo<T extends Enum<?> & Bar> { 

    final Class<T> clazz; 

    public Foo(Class<T> clazz) { 

     this.clazz = clazz; 
    } 

    public void baz() { 

     T[] constants = clazz.getEnumConstants(); 

     System.out.println(Arrays.toString(constants)); 
    } 

    public static void main(String[] args) { 

     new Foo<MyEnum>(MyEnum.class).baz(); //prints "[A, B, C, D]" 
    } 
} 

public interface Bar { } 

public enum MyEnum implements Bar { A, B, C, D; } 
+2

Bu yüzden, Tip Silme işleminin etrafından dolaşıp, "T" olarak geçilen sınıfa ulaşmamın bir yolu yok.Bu iş parçacığının fikri, tip silme işleminin herhangi bir yolu olup olmadığını bulmaktır. –

+1

@Chris - Yansıma, Java'daki silmeyi yazmanın tek geçici yoludur. Ancak, 'Class' nesnesinde geçirerek sahip olduğunuz şeyden daha fazla dezavantaj yaratmıyorsunuz, ancak rahatsız edici ve derleme zamanında gereksiz görünüyor. Sınıf # getEnumConstants() 'ı kullanarak yansımayı zaten kullandığınıza dikkat edin. Tek alternatif, bu yönteme olan bağımlılığınızı ortadan kaldıran tam bir yeniden tasarlamadır. –

1

Neil Gafter tarafından önerilen şekilde bir süper tip belirteci kullanın ve bu amaç için kılavuz gibi kütüphaneler tarafından kullanılır.

Özgün açıklama için bkz. http://gafter.blogspot.com/2006/12/super-type-tokens.html CA radyo ömrü çalışma uygulaması için kılavuz kaynağını kontrol ediyorum.

Richard Gomes önerdiği bir çözümü kullanabilirsiniz Bazı durumlarda satır içi burada How can I pass a Class as parameter and return a generic collection in Java?

0

çalışmış örnekle bir cevabı var başka q yoktur. Anonim sınıf örnekleri oluştururken, type parametre sınıfı bilgisi kullanılabilir. Bu şekilde oluşturulan birden çok örneği farklı bir anonim sınıfların olacak ve bu bir sorun varsa yeni çağrıları yerine klon dayalı bir createnew() fonksiyonu ile bir sınıf A_String_Factory isteyebilirsiniz

class A<T> 
{ 
    A() 
    { 
     java.lang.reflect.ParameterizedType parameterizedType = (java.lang.reflect.ParameterizedType) (this.getClass().getGenericSuperclass()); 
     System.out.println(parameterizedType.getActualTypeArguments()[0]); 
    } 
} 

public class Example { 
public static void main(String[] args) { 
    A<String> anonymous = new A<String>() {}; // prints java.lang.String 
} 
} 

Not.

İlgili konular