简体   繁体   中英

How to correctly call a method with parameter of generic type and get rid of the “unchecked call to member of raw type” warning

I have created a base class for different subclasses of adapters for my list, which it has a List field with generic type. The code of the class is as below:

public class ListBaseAdapter<T> extends BaseAdapter {
    private List<T> items;

    @Override
    public int getCount() {
        if (items==null)
            return 0;
        return items.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return null;
    }

    List getDataset() {
        return items;
    }

    public void setDataset(List<T> items) {
        this.items = items;
    }
}

Also, below is some example of different subclasses to it:

public class UserListAdapter extends ListBaseAdapter {...}
public class AddressListAdapter extends ListBaseAdapter {...}

In the ListFragment, a ListBaseAdapter field is declared and initialised according to different type of lists shown.

public class TheListFragment extends ListFragment {
    private ListBaseAdapter adapter;

    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        ...
        switch(type) {
            case 1:
                adapter = new UserListAdapter();
                adapter.setDataset(users); // this line of code is getting the warning of "unchecked call to member of raw type"
                break;
            case 2:
                adapter = new AddressListAdapter();
                adapter.setDataset(addresses); // this line of code is getting the warning of "unchecked call to member of raw type"
                break;
        }
        setListAdapter(adapter);
    }
}

The code is just work fine, also I know that by setting a Type to the ListBaseAdapter such as the example below will get rid of the warning:

private ListBaseAdapter<Users> adapter;

but if I'm doing so, I will have to prepare multiple adapters in the ListFragment which each with a specific type.

I am wondering if there is a way to get rid of the warning (not using Lint) but still maintain only one adapter field or am I correctly doing this way of coding?

For your example cases, you should also initialize them with a type, ie:

public class UserListAdapter extends ListBaseAdapter<Users> {...}
public class AddressListAdapter extends ListBaseAdapter<Address> {...}

If you want to maintain only a single reference but still be able to pass in specific types, then given the code you provided, what I'd recommend would be something along these lines:

public class TheListFragment extends ListFragment {
    // You really don't even need to keep a reference to this
    // since it can be retrieved with getListAdapter()
    private ListBaseAdapter<?> adapter;

    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        ...
        switch(type) {
            case 1:
                UserListAdapter userAdapter = new UserListAdapter();
                userAdapter.setDataset(users);
                adapter = userAdapter;
                break;
            case 2:
                AddressListAdapter addressAdapter = new AddressListAdapter();
                addressAdapter.setDataset(addresses);
                adapter = addressAdapter;
                break;
        }

        setListAdapter(adapter);
    }
}

Provided you don't need to make future data assignments to the adapter, that will do the trick. Your field is only of type ListBaseAdapter<?> , but your local variables are of the specific type, so you can work with them directly, and then assign them to the more weakly-typed field adapter .

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM