Home > Mobile >  Java, Type mismatch when extending abstract class
Java, Type mismatch when extending abstract class

Time:05-20

I don't understand why data.entrySet() and data.keySet() in the code below are giving me Type Mismatch in eclipse, though I specified the type in both cases in the for loop.

Is this normal or am I missing something that should I take into account when extending an abstract class?

import java.util.AbstractSet;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;


abstract class SetDuplicates<K> extends AbstractSet {

    public Map<K, Integer> data;
}

class TreeSetDuplicates<K> extends SetDuplicates {

    public TreeSetDuplicates() {
        data = new TreeMap<K, Integer>();
    }

    public Object first() {
    
    for (Map.Entry<K, Integer> entry : data.entrySet()) {}
    
    for (K element : data.keySet()) {}

    }

    @Override
    public Iterator iterator() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int size() {
        // TODO Auto-generated method stub
        return 0;
    }

}

This is the Eclipse Error: enter image description here

CodePudding user response:

Your generics are out of whack. You are getting a warning on the line class TreeSetDuplicates<K> extends SetDuplicates {, and when the compiler gives you warnings you don't understand perhaps it is best to focus on those first.

The problem is, every mention of SetDuplicates needs to carry with it which type you'd like to use for its <K> type parameter. Failure to do this makes it a raw type reference, and when you do that, all generics poof out of existence. Hence, given that SetDuplicates is now raw, so is data, and therefore, so is all mention of K or V in any method you care to call on data. Thus, data.entrySet() just returns a raw Map.Entry object, and you can't just elect to stick the <K, Integer> limit on this: A compiler error occurs instead.

Fix the root cause and all problems go away: class TreeSetDuplicates<K> extends SetDuplicates<K> {} and off you go.

Let's say you have:

class Bar<Z> {}
class Foo<K> extends Bar<K> {}

In class Foo<K> extends Bar<K>, the first use of <K> declares a type variable: You are saying: Any mention of this type has a type variable, and we shall call it K.

The second use is you using this: You're saying: You extend Bar, and as with any time you mention Bar anywhere, you need to pick what you want to use for Bar's Z type variable. You shall choose K - your own type variable. That's why the letters are not required to be the same letter - they are in your case, which means you're shadowing out the K from your superclass with your own K. This is fine - they are the same type after all. But it shows why you need that <K> twice: Same syntax, but utterly different meaning - first declares, second uses.

CodePudding user response:

It's because generic parameter K does not shared between the interface and the class. Change class header as below will resolve the issue.

class TreeSetDuplicates<K extends Object> extends SetDuplicates<K>
  •  Tags:  
  • java
  • Related