2016-07-02 24 views
8

'da jenerik tür kullanıldığında "Bilinmeyen türle karşılaşıldı" Öğelerin listesini okumak için işlev oluşturduğum genel türde bir sınıf oluşturmaya çalışıyorum. Ve bunu yapmanın 2 yolunun olduğunu biliyorum: (# 1) her öğeyi bir döngüde okuyarak veya (# 2) doğrudan bir varlık haritası oluştur.Firebase GenericTypeIndicator

2 daha etkilisi görünüyor ama maalesef GenericTypeIndicator cins çalışmıyor - kod kullanıldığında bir o IllegalStateException: Unknown type encountered: T döndürür: Yani

Map<String, T> entityMap = 
    dataSnapshot.getValue(new GenericTypeIndicator<Map<String, T>>() {}); 

:

  1. herhangi bir yolu var mı Genel varlıklar türünü doğrudan bir haritaya mı okuyorsunuz? (# 2)
  2. Ya da sadece döngüdeki varlıkları (# 1) okurken performansta önemli bir fark yok mu?
public class SomeClass<T extends KeyEntity> { 

    private final Class<T> mGenericClass; 
    private final String mRefKey; 

    public SomeClass(Class<T> clazz, String refKey) { 
     mGenericClass = clazz; 
     mRefKey = refKey; 
    } 

    public class KeyEntity { 
     private String mKey; 

     public KeyEntity() {} 

     public String getKey() { 
      return mKey; 
     } 

     public void setKey(String key) { 
      mKey = key; 
     } 
    } 

    public interface EntityListListener<T> { 
     abstract public void onEntityListLoaded(List<T> entity); 
    } 

    public void loadAll(final EntityListListener<T> entityListListener) { 
     DatabaseReference dbRef = FireDbUtils.getReference(mRefKey); 
     dbRef.addListenerForSingleValueEvent(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
      List<T> entityList = new ArrayList<>((int) dataSnapshot.getChildrenCount()); 

      // #1 - read each entity in a loop 
      for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) { 
       T entity = dataSnapshot.getValue(mGenericClass); 
       entity.setKey(childSnapshot.getKey()); 
       entityList.add(entity); 
      } 

      // #2 - read all entity into a map 
      // GenericTypeIndicator doesn't like generic type 
      // if used, it returns "IllegalStateException: Unknown type encountered: T" 
      Map<String, T> entityMap 
       = dataSnapshot.getValue(new GenericTypeIndicator<Map<String, T>>() {}); 
      for (Map.Entry<String, T> pair : entityMap.entrySet()) { 
       T entity = pair.getValue(); 
       entity.setKey(pair.getKey()); 
       entityList.add(entity); 
      } 

      entityListListener.onEntityListLoaded(entityList); 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) {} 
    }); 
} 

örn. veriler:

{ 
    carList: { 
     carKey1: { 
      name: "wife car" 
     }, 
     carKey2: { 
      name: "my best car in the world ever" 
     } 
    }, 
    garageList: { 
     garageKey1: { 
      name: "house garage" 
     }, 
     garageKey2: { 
      name: "top secret garage under main garage" 
     } 
    } 
} 

cevap

1

Kullanım ParameterizedType genel sınıf nesneyi bulmak için

ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass(); 
//all generic classes  
Type[] args = type.getActualTypeArguments(); 

Class<T> genericClass = (Class<T>) args[0]; 

T entity = dataSnapshot.getValue(genericClass);