Sobes.tech
Middle

Wo haben Sie Generics in Ihrer Entwicklungserfahrung verwendet?

sobes.tech KI

Antwort von AI

Verwendung von Generics:

  • Zur Implementierung typsicher Sammlungen. Zum Beispiel ArrayList<MyObject> anstelle von rohen ArrayList, was Laufzeitfehler im Zusammenhang mit Typumwandlungen verhindert.
    // Unsicherer Ansatz (roher Typ)
    List list = new ArrayList();
    list.add("String");
    list.add(123); // Fügt int hinzu
    
    // Typsicherer Ansatz mit Generics
    List<String> stringList = new ArrayList<>();
    stringList.add("String");
    // stringList.add(123); // Compiler gibt Fehler aus
    
  • Für die Erstellung universeller Adapter für RecyclerView. Ermöglicht die Wiederverwendung der Adapterlogik für verschiedene Datentypen.
    // Beispiel eines generischen ViewHolder
    class GenericViewHolder<T>(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(item: T) {
            // Logik zum Binden von Daten je nach Typ T
        }
    }
    
    // Beispiel eines generischen Adapters
    class GenericAdapter<T>(private val items: List<T>) : RecyclerView.Adapter<GenericViewHolder<T>>() {
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GenericViewHolder<T> {
            // ViewHolder erstellen
        }
    
        override fun onBindViewHolder(holder: GenericViewHolder<T>, position: Int) {
            holder.bind(items[position])
        }
    
        override fun getItemCount() = items.size
    }
    
  • Für die Erstellung von Fabriken von Objekten. Um einen bestimmten Objekttyp ohne explizite Konvertierung zu erhalten.
    interface Factory<T> {
        T create();
    }
    
    class StringFactory implements Factory<String> {
        @Override
        public String create() {
            return "Neue Zeichenkette";
        }
    }
    
    class IntegerFactory implements Factory<Integer> {
        @Override
        public Integer create() {
            return 100;
        }
    }
    
    Factory<String> stringFactory = new StringFactory();
    String myString = stringFactory.create(); // Erhält einen String ohne Konvertierung
    
  • Zur Einschränkung von Typen in Methoden und Klassen. Verwendung von beschränkten Generics (<T extends MyInterface> oder <T super MyClass>) um sicherzustellen, dass der generische Typ eine bestimmte Schnittstelle implementiert oder von einer bestimmten Klasse erbt.
    // Methode, die eine Liste von Elementen akzeptiert, die Serializable implementieren
    public <T extends Serializable> void saveObjectList(List<T> list) {
        // Logik zum Speichern
    }
    
  • In architektonischen Komponenten. Zum Beispiel bei der Arbeit mit LiveData oder ViewModel, bei denen häufig Generics verwendet werden, um den Datentyp zu definieren, den sie verwalten.
    // LiveData für eine Liste von Objekten eines bestimmten Typs
    val myData: LiveData<List<MyItem>> = // Initialisierung
    
    // ViewModel mit Daten eines bestimmten Typs
    class MyViewModel : ViewModel() {
        val data: MutableLiveData<MyStateType> by lazy {
            MutableLiveData<MyStateType>()
        }
    }
    
  • Bei der Entwicklung von Netzwerk-Clients. Für die automatische Deserialisierung von Serverantworten in Objekte eines bestimmten Typs.
    // Beispiel eines Retrofit-Services mit generischer Antwort
    interface ApiService {
        @GET("users")
        Call<List<User>> getUsers();
    
        @GET("products/{id}")
        Call<Product> getProduct(@Path("id") String productId);
    }
    

Generics haben die Typsicherheit, Lesbarkeit und Wiederverwendbarkeit des Codes erheblich verbessert.