Buffalo
Buffalo

Reputation: 4042

concrete parameter type vs wildcard signature

I'm trying to use a wildcard type in a method signature and pass different parameterized types. If I parameterize a Map with my item, Eclipse starts complaining:

The method DoStuff(Map<String,Test.GenericItemWrapper<?>>) in the type Test 
is not applicable for the arguments (Map<String,Test.GenericItemWrapper<String>>)

Here's the code:

import java.util.Map;

public class Test
{

  public static void main(String[] args)
  {
    Map<String, GenericItemWrapper<Long>> longWrapper = null;
    Map<String, GenericItemWrapper<String>> stringWrapper = null;

    Test t = new Test();
    t.DoStuff(longWrapper); // error here
    t.DoStuff(stringWrapper); // error here
  }

  public void DoStuff(Map<String, GenericItemWrapper<?>> aParam)
  {

  }

  public static class GenericItemWrapper<ItemType>
  {
    private ItemType mItem;

    public GenericItemWrapper()
    {
      this(null);
    }

    public GenericItemWrapper(ItemType aItem)
    {
      mItem = aItem;
    }

  }
}

Upvotes: 0

Views: 42

Answers (2)

amorfis
amorfis

Reputation: 15770

The problem is that Map<String,Test.GenericItemWrapper<String>> is not instance of Map<String,Test.GenericItemWrapper<?>>, even if String is kind of "instance of" ?.

Just like List<String> is not assignable to a variable of type List<Object>. In Java there is no type covariance ( https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science) )

Upvotes: 0

Murat Karag&#246;z
Murat Karag&#246;z

Reputation: 37584

You are missing the parameter for instantiating GenericItemWrapper. Should be

GenericItemWrapper<Long> longWrapper = new GenericItemWrapper<Long>(1l); // example number

but you don't need that constructor as far as I can see since you can always access the generic type ItemType within the class.

Upvotes: 1

Related Questions