I have a Adapter in my Android app and I want to make it Generic.
Basiclly the Adapter looks like that:
public class myAdapter extends FragmentStatePagerAdapter {
DataTypaA myFragment;
DataTypeB data;
DataTypeC items;
public myAdapter(FragmentManager fm, DataTypaA fragment) {
data = new SparseArray<DataTypeB>();
myFragment = fragment;
items = myFragment.getData();
}
public DataTypeB getItem(int position) {
return data.get(position);
}
@Override
public int getCount() {
return items.getList().size();
}
public void setData () {
items = myFragment.getItems () //getItems return DataTypeC
data.setTheData (items)
}
}
I changed it to generic
public class myAdapter <A,B,C> extends FragmentStatePagerAdapter {
A myFragment;
B data;
C items;
public myAdapter(FragmentManager fm, A fragment) {
data = new SparseArray<B>();
myFragment = fragment;
items = (C) myFragment.getData();
}
public B getItem(int position) {
return data.get(position);
}
@Override
public int getCount() {
return items.getList().size();
}
public void setData () {
items = myFragment.getItems () //getItems return DataTypeC
data.setTheData (items)
}
}
but I'm getting different errors, when methods should get DataTypeC
parameter and I passing it parameter type C
( data.setTheData (items)
) that is actually type DataTypeC
the compiler suggest to cast C
to type DataTypeC
. and in getCount()
I have also error suggesting to convert items
to DataTypeC
.
for example when I try to override getItem I getting mistakes, but when I create the same method with other name it compiles.
//Error - "The return type is incompatible with FragmentStatePagerAdapter.getItem(int)"
@Override
public B getItem(int position) {
return (B) data.get(position);
}
//compiles
public B getItemTest(int position) {
return data.get(position);
}
Any ideas how to fix it so it will be 100% generic?
ADDED : After your answer I changes it to support return of generic type :
public class TypeA <T> {
private T mData;
public T getData() { return mData;; }
}
public class myAdapter <A,B,C> extends FragmentStatePagerAdapter {
A myFragment;
B data;
C items;
public myAdapter(FragmentManager fm, A fragment) {
data = new SparseArray<B>();
myFragment = fragment;
items = myFragment.getData(); //Error - The method getData() is undefined for the type T
}
}
I'm getting compile error... when I run it of course <T>
and <C>
are the same type.
The first problem is that your non-generic code doesn't compile. You have a field DataTypeB data;
which you then assign a SparseArray<DataTypeB>
to. Also, setData
doesn't compile at all.
Ignoring this... you have declared type parameters A, B, C
and changed your instance field types, but you still try and assign DataTypaA
to A myFragment
in your constructor, and a SparseArray<DataTypeB>
to B data
. When you migrate code to generics you need to approach it like you would refactoring - one step at a time.
For instance, by diving in as you have now take a look at items = (C)myFragment.getData()
. As fragment
is still of type DataTypaA
then presumably its getData()
method doesn't return a generic type. Something is going to have to change.
You have a lot of work to do, so to repeat myself - treat this as a refactoring exercise and go step by step.
myFragment
to be a A myFragment
and declare a type parameter <A extends DataTypaA
. See what needs to be done to get this to compile before moving on. data
to be SparseArray<B> data
. Presumably this needs to a SparseArray<T>
where T
is a DataTypeB
, or subtype thereof. That means you are going to need a wildcard-based bound on B
. Something like B extends SparseArray<? extends DataTypeB>
B extends SparseArray<? extends DataTypeB>
items
. You know that it is returned from your new generic type variable A extends DataTypeA
, so DataTypeA
needs to be generic and have a generic type variable returned from getData
. Let's say it is declared as DataTypeA<T extends DataTypeC>
with public T getData() { ... }
. So now your type parameter sections change to:
class DataTypaA<T extends DataTypeC>
...
class myAdapter <A extends DataTypaA<C>,
B extends SparseArray<? extends DataTypeB>,
C extends DataTypeC>
extends FragmentStatePagerAdapter {
A myFragment;
SparseArray<B> data;
C items;
...
It's hard to go too far with this given the code you have posted - not all the classes and information is there, but this is the process you will have to follow.
For instance: you may not need to restrict C
to DataTypeC
. This then changes the type parameter sections on myAdapter
and DataTypeA
. My assumption about SparseArray<B>
may also be incorrect - but your code doesn't compile at the moment so I can't tell. A final implementation may go something like:
class myAdapter <A extends DataTypaA<C>,
B extends SparseArray<? extends DataTypeB,
? extends DataTypeC>,
C extends DataTypeC>
extends FragmentStatePagerAdapter {
A myFragment;
SparseArray<B, C> data;
C items;
public myAdapter(FragmentManager fm, A fragment) {
data = new SparseArray<B, C>();
myFragment = fragment;
items = myFragment.getData();
}
public B getItem(int position) {
return data.get(position);
}
@Override
public int getCount() {
return items.getList().size();
}
public void setData () {
items = myFragment.getItems (); //getItems return DataTypeC
data.setTheData(items);
}
}
For this I used the fake classes:
class DataTypaA<T extends DataTypeC> {
public T getData() { return null; }
public T getItems() { return null; }
}
class SparseArray<T, S> {
public T get(int foo) { return null; }
public void setTheData(S items){}
}
class DataTypeB {
}
class DataTypeC {
// do NOT use the raw type List - just done to get your code to compile
public List getList() { return null; }
}
abstract class FragmentStatePagerAdapter {
public abstract int getCount();
}
class FragmentManager {
}
When "genericizing" classes, you should replace all instances of genericized types by their generic: DataTypaA
becomes A
, etc.
You also need to make sure return types from methods you call on other objects (like fragment.getData()
) are compatible with the generic. For that you can indicate the generic type extends a known class:
public class MyAdapter<A extends MyData,B extends MyData,...>
The Java Tutorial on generics is good for more information.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.