简体   繁体   中英

a java generic programming question

I have a class A like this:

public class A<T extends Number>
{
 ....
}

In another class I have this method:

public Hashtable<String, A> createAHashtable()
    {
        Hashtable<String, A> hTable = new Hashtable<String, A>();

        return hTable;
    }

There is a warning for parameter A because it is generic class. So should I do this:

public Hashtable<String, A <?>> createAHashtable()
        {
            Hashtable<String, A<?>> hTable = new Hashtable<String, A<?>>();

            return hTable;
        }

or do this:

public Hashtable<String, A <? extends Number>> createAHashtable()
{
Hashtable<String, A<? extends Number> hTable = new Hashtable<String, A<? extends Number>();

return hTable;
}

or ....???

EDIT:

Tried this (as suggested by Dilum)

public <T extends Number> Hashtable<String, A<T>> createAHashtable()
    {
        Hashtable<String, A<T>> hTable = 
                new Hashtable<String, A<T>>();
        A<Float> constraint = new A<Float>();
        hTable.put("test", constraint);

        return hTable;
    }

But it is invalid to "put" my Float A.

Maybe the wildcard is the way to go.

EDIT 2:

Based on Dilum's suggestion, the following code (cast to A when put a Float A into the Hashtable) has no error but warning it is unsafe cast. Why we need the cast?

public <T extends Number> Hashtable<String, A<T>> createAHashtable()
        {
            Hashtable<String, A<T>> hTable = 
                    new Hashtable<String, A<T>>();
            A<Float> constraint = new A<Float>();
            hTable.put("test", (A<T>)constraint);

            return hTable;
        }

Try this:

public <T extends Number> Hashtable<String, A<T>> createAHashtable() {
  return new Hashtable<String, A<T>>();
}

Say you did want to pre-fill with a key-value pair, try:

public <T extends Number> Hashtable<String, A<T>> createAHashtableWithEntry(String key, T value) {
  Hashtable<String, A<T>> ht = return new Hashtable<String, A<T>>();
  ht.put(key, new A<T>(value));
  return ht;
}

Related to edit 2:

Here's a concrete example of why the case is unsafe. On my IDE I actually don't even get a warning that the cast is unsafe.

import java.util.ArrayList;
import java.util.List;

public class Genericss {

   static <T extends Number> List<A<T>> get2() {
      List<A<T>> list = new ArrayList<A<T>>();
      A<Float> f = new A<Float>(3.0f);
      list.add((A<T>) f); // Compiles... not even a warning on my IDE
      return list;
   }

   public static void main(String[] args) {
      List<A<Integer>> l = Genericss.<Integer>get2();
      Integer i = l.get(0).get(); // runtime error

      A<Float> f = new A<Float>(3f);
      //i = (A<Integer>) f;  // won't compile
   }

   public static class A<T> {
      T t;

      public A(T t) {
         this.t = t;
      }

      public T get() {
         return t;
      }
   }
}

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