Uses unchecked or unsafe operations

2019-07-15 02:34发布

问题:

I keep getting an error that says: Note: ABag.java uses unchecked or unsafe operations.

I googled it and found this post, and made the changes that I thought would remove the error but I continue to get the error.

Is there anything else I can do to stop getting this error message?

public class ABag<Item> implements BagInterface<Item>
{
private ArrayList<Item> bag;

//creates an empty bag
public ABag(){
    bag = new ArrayList<Item>();
}

//creates an empty set with initial capacity
public ABag (int initialCapacity){
    bag = new ArrayList<Item>(initialCapacity);
}


public boolean add(Item newEntry){
    if (newEntry == null)
        return false;
    else
    {
        bag.add(newEntry);
        return true;
    }
}


public boolean isFull(){
    return false;
}


public Item[] toArray(){
    Item[] temp = (Item[])bag.toArray();
    return temp;
}


public boolean isEmpty(){
    return false;
}


public int getCurrentSize(){
    return bag.size();
}


public int getFrequencyOf(Item anEntry){
    int count = 0;
    if (!(bag.contains(anEntry)))
    {
        for (int i=0;i<bag.size();i++)
        {
            if (bag.get(i) == anEntry)
                count++;
        }
    }
    return count;
}


public boolean contains(Item anEntry){
    return bag.contains(anEntry);
}


public void clear(){
    bag.clear();
}


public Item remove(){
    int size = bag.size();
    Item removed = bag.remove(size-1);
    return removed;
}


public boolean remove(Item anEntry){
    return bag.remove(anEntry);
}
}

Thank you in advance!

回答1:

You should enable linting to get verbose warnings about the specific problems:

javac -Xlint:all ...

Among other things, toArray() is broken. The List.toArray() method returns an Object[], not an array of <T>, so your cast to (Item[]) is incorrect and will fail at runtime. You should be using <T> T[] toArray(T[] a).

In order to create an array of the generic type (possibly the biggest weakness of Java generics), you need to pass in the Class for the target type and use reflection and suppress the warning, like so:

static public <T> T[] create(Class<T> typ, int len) {
    return uncheckedCast(java.lang.reflect.Array.newInstance(typ,len));
}

@SuppressWarnings("unchecked")
static public <T> T uncheckedCast(final Object obj) {
    return (T)obj;
}

The other option is to push the problem back one layer to the code that can be assumed to know the correct type and pass an array of that type into your toArray method, just as the Collections API does:

public Item[] toArray(Item[] dummy) {
    return this.bag.toArray(dummy);
}

As something of an aside, convention is to use a single uppercase letter for the generic type; your use of <Item> fooled me at first when I was looking at toArray in isolation.



回答2:

Replace your toArray with this, to avoid the cast

public Item[] toArray(){
    Item[] temp = bag.toArray(new Item[0]);
    return temp;
}