Sobes.tech
Middle

Kde jste ve své vývojové zkušenosti použili generika?

sobes.tech AI

Odpověď od AI

Obecně používané generické:

  • Pro implementaci typově bezpečných kolekcí. Například ArrayList<MyObject> místo surového ArrayList, což zabraňuje chybám při běhu souvisejícím s přetypováním.
    // Nesprávný přístup (surový typ)
    List list = new ArrayList();
    list.add("Řádek");
    list.add(123); // Přidání int
    
    // Typově bezpečný přístup s generiky
    List<String> stringList = new ArrayList<>();
    stringList.add("Řádek");
    // stringList.add(123); // Kompilátor hlásí chybu
    
    
  • Pro tvorbu univerzálních adaptérů RecyclerView. Umožňuje znovu použít logiku adaptéru pro různé datové typy.
    // Příklad univerzálního ViewHolderu
    class GenericViewHolder<T>(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(item: T) {
            // Logika vázání dat podle typu T
        }
    }
    
    // Příklad univerzálního adaptéru
    class GenericAdapter<T>(private val items: List<T>) : RecyclerView.Adapter<GenericViewHolder<T>>() {
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GenericViewHolder<T> {
            // Vytvoření ViewHolderu
        }
    
        override fun onBindViewHolder(holder: GenericViewHolder<T>, position: Int) {
            holder.bind(items[position])
        }
    
        override fun getItemCount() = items.size
    }
    
  • Pro tvorbu továren objektů. Získání konkrétního typu objektu bez nutnosti explicitního přetypování.
    interface Factory<T> {
        T create();
    }
    
    class StringFactory : Factory<String> {
        override fun create(): String {
            return "Nový řádek";
        }
    }
    
    class IntegerFactory : Factory<Int> {
        override fun create(): Int {
            return 100;
        }
    }
    
    Factory<String> stringFactory = StringFactory();
    val myString: String = stringFactory.create(); // Získání String bez přetypování
    
  • Pro omezení typů v metodách a třídách. Použití omezených generik (<T extends MyInterface> nebo <T super MyClass>) k zajištění, že typ generik implementuje určité rozhraní nebo dědí z určité třídy.
    // Metoda, která přijímá seznam prvků implementujících rozhraní Serializable
    public <T extends Serializable> void saveObjectList(List<T> list) {
        // Logika ukládání
    }
    
  • V architektonických komponentách. Například při práci s LiveData nebo ViewModel, často se používají generika k určení typu dat, který spravují.
    // LiveData pro seznam objektů určitého typu
    val myData: LiveData<List<MyItem>> = // inicializace
    
    // ViewModel s daty určitého typu
    class MyViewModel : ViewModel() {
        val data: MutableLiveData<MyStateType> by lazy {
            MutableLiveData<MyStateType>()
        }
    }
    
  • Při vývoji síťových klientů. Pro automatickou deserializaci odpovědí ze serveru do konkrétních typů objektů.
    // Příklad Retrofit služby s generikem v odpovědi
    interface ApiService {
        @GET("users")
        Call<List<User>> getUsers();
    
        @GET("products/{id}")
        Call<Product> getProduct(@Path("id") String productId);
    }
    

Generika výrazně zvýšila typovou bezpečnost, čitelnost a možnost znovupoužití kódu.