Middle
Gde ste koristili generike u svom iskustvu razvoja?
sobes.tech АИ
Одговор од АИ
Opšte korišćeni generici:
- Za implementaciju tip-bezbednih kolekcija. Na primer,
ArrayList<MyObject>umesto sirovogArrayList, što sprečava greške tokom izvršavanja povezane sa konverzijom tipova.// Nije tip-bezbed pristup (sirovi tip) List list = new ArrayList(); list.add("Red"); list.add(123); // Dodavanje int // Tip-bezbed pristup sa generičkim tipovima List<String> stringList = new ArrayList<>(); stringList.add("Red"); // stringList.add(123); // Kompajler će prikazati grešku - Za kreiranje univerzalnih adaptera za RecyclerView. Omogućava ponovno korišćenje logike adaptera za različite tipove podataka.
// Primer univerzalnog ViewHolder-a class GenericViewHolder<T>(itemView: View) : RecyclerView.ViewHolder(itemView) { fun bind(item: T) { // Logika za povezivanje podataka u zavisnosti od tipa T } } // Primer univerzalnog adaptera class GenericAdapter<T>(private val items: List<T>) : RecyclerView.Adapter<GenericViewHolder<T>>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GenericViewHolder<T> { // Kreiranje ViewHolder-a } override fun onBindViewHolder(holder: GenericViewHolder<T>, position: Int) { holder.bind(items[position]) } override fun getItemCount() = items.size } - Za kreiranje fabričkih funkcija za objekte. Za dobijanje konkretnog tipa objekta bez eksplicitnog prebacivanja.
interface Factory<T> { T create(); } class StringFactory : Factory<String> { override fun create(): String { return "Novi red"; } } class IntegerFactory : Factory<Int> { override fun create(): Int { return 100; } } Factory<String> stringFactory = StringFactory(); val myString: String = stringFactory.create(); // Dobijamo String bez prebacivanja - Za ograničavanje tipova u metodama i klasama. Korišćenje ograničenih generičkih tipova (
<T extends MyInterface>ili<T super MyClass>) za garantovanje da generički tip implementira određeni interfejs ili nasleđuje od određene klase.// Metod koji prihvata listu elemenata koji implementiraju interfejs Serializable public <T extends Serializable> void saveObjectList(List<T> list) { // Logika za čuvanje } - U arhitektonskim komponentama. Na primer, pri radu sa LiveData ili ViewModel, često se koriste generički tipovi za definisanje tipa podataka kojima upravljaju.
// LiveData za listu objekata određenog tipa val myData: LiveData<List<MyItem>> = // inicijalizacija // ViewModel sa podacima određenog tipa class MyViewModel : ViewModel() { val data: MutableLiveData<MyStateType> by lazy { MutableLiveData<MyStateType>() } } - Pri razvoju mrežnih klijenata. Za automatsku deserializaciju odgovora sa servera u konkretne tipove objekata.
// Primer Retrofit servisa sa generičkim u odgovoru interface ApiService { @GET("users") Call<List<User>> getUsers(); @GET("products/{id}") Call<Product> getProduct(@Path("id") String productId); }
Generici su značajno povećali tip-bezbednost, čitljivost i mogućnost ponovne upotrebe koda.