[Android] 제네릭(Generic) 이란?
제네릭(Generic)
클래스나 메서드에서 데이터 타입을 지정하지 않고, 사용할 때 타입을 결정할 수 있도록 하는 기능
- 코드 재사용성 증가 → 여러 데이터 타입에 대해 하나의 클래스로 처리 가능
- 타입 안정성 보장 →
ClassCastException방지 - 유연성 증가 → 다양한 데이터 타입을 처리할 수 있음
제네릭 사용 예제
public abstract static class Adapter<T, E extends ViewDataBinding>
extends RecyclerView.Adapter<ViewHolder<E>> {
T→ 리스트에서 사용할 데이터 타입 (예:String,User,Product등)E extends ViewDataBinding→ViewDataBinding을 확장한 데이터 바인딩 클래스만 사용 가능 (타입 제한)ViewHolder<E>→E타입을 사용하는 ViewHolder
제네릭을 활용한 코드 설명
- (1) 제네릭을 사용하지 않는 경우
public class StringAdapter extends RecyclerView.Adapter<StringViewHolder> { private List<String> items; @Override public void onBindViewHolder(StringViewHolder holder, int position) { holder.bind(items.get(position)); } }- 만약
Integer타입 리스트가 필요하면IntegerAdapter를 따로 만들어야 함 → 중복 코드 발생 - 코드 중복 증가
- 만약
- (2) 제네릭을 사용하는 경우
public abstract static class Adapter<T, E extends ViewDataBinding> extends RecyclerView.Adapter<ViewHolder<E>> { private List<T> mItems = new ArrayList<>(); @Override public void onBindViewHolder(ViewHolder<E> holder, int position) { holder.onBindViewHolder(mItems.get(position)); } }T→ 어떤 데이터 타입이든 사용할 수 있도록 유연성 증가E→ViewDataBinding을 상속받는 클래스만 가능 (타입 안전성 확보)
Android Framework / Hidden API
1. getSystemService 래핑
public static <T> T getService(Context context, String name) {
return (T) context.getSystemService(name);
}
- 사용
TelephonyManager tm = getService(context, Context.TELEPHONY_SERVICE);
2. Field 접근
- Field는 클래스 안에 선언된 변수(멤버 변수) 를 다루는 Reflection 객체
public static <T> T getField(Object obj, String fieldName) throws Exception { Field field = obj.getClass().getDeclaredField(fieldName); field.setAccessible(true); return (T) field.get(obj); }field.setAccessible(true): private라서 못 건드리는 것을 강제로 접근field.get(obj): bj 인스턴스 안에 들어있는 해당 필드 값을 가져옴
3. Method invoke
- Method는 클래스 안의 메서드(함수) 를 나타내는 Reflection 객체
- 메서드 자체를 꺼내서 실행
public static <T> T call(Object obj, String methodName, Object... args) throws Exception { Method method = obj.getClass().getDeclaredMethod(methodName); method.setAccessible(true); return (T) method.invoke(obj, args); }method.setAccessible(true): private 메서드 접근 가능하게 변경method.invoke(obj, args): 함수를 Reflection으로 실행
Leave a comment