如果使用泛型类型参数声明一个类,并且在未指定类型的情况下实例化它,它是否默认为Object?

时间:2013-12-07 02:01:20

标签: java object generics linked-list queue

如果没有指定默认类型,我已经看到了很多关于是否可以指定默认类型的问题。答案似乎是否定的。我的问题是,如果你的类标题需要一个类型参数,并且你只是不传递一个, 它默认为什么?宾语?采用Queue(缩写)的简单链接节点实现:

public class ListQueue<T> implements Queue<T>
{
   private Node<T> first;
   private Node<T> last;

   public void enqueue(T item)
   {
      Node<T> x = new Node<T>(item);
      if (isEmpty())
      {
         first = x;
         last = x;
      }
      else
      {
         last.next = x;
         last = x;
      }
   }

   public T dequeue()
   {
      if (isEmpty())
      {
         throw new IllegalStateException("Queue is empty");
      }
      T item = first.data;
      first = first.next;
      if (isEmpty())
      {
         last = null;
      }
      return item;
   }
}

public class Node<T>
{
   public T data;
   public Node<T> next;

   public Node(T data)
   {
      this(data, null);
   }

   public Node(T data, Node<T> n)
   {
      this.data = data;
      next = n;
   }
}

然后在我的测试驱动程序中,我似乎能够将任何类型的数据排队/出列:

public static void main(String[] args)
{
   ListQueue myQueue = new ListQueue();  // key point: no type specified

   myQueue.enqueue("test");
   myQueue.enqueue(2);
   myQueue.enqueue(new Date());

   System.out.println(myQueue.dequeue()); // prints "test"

   int result = 2 + (Integer)myQueue.dequeue();
   System.out.println(result); // prints 4

   Date now = (Date)myQueue.dequeue();
   System.out.println(now); // prints current date
}

当然,我必须抛出一切违背泛型目的的东西,但它是否真的将我的数据项默认为对象以允许它们全部进入队列?这是我能想到的唯一解释,但我想确认一下,因为我找不到具体写出来就是这种情况。

3 个答案:

答案 0 :(得分:5)

是的,如果您未指定类型,则默认为Object但是你应该避免使用原始类型,并且应该尽可能多地使用泛型,因为泛型在编译时提供更严格的类型检查。

必须知道类型参数仅在运行时保留,即运行时类型参数已擦除且此过程称为Type Erasure

答案 1 :(得分:1)

这是java 1.4以前的工作方式。 Generics是作为java 1.5的一部分引入的,因此我们可以更好地控制我们放入Collections和我们检索的内容。这样做是为了最大限度地减少运行时可能出现的错误。

要回答您的问题,它会默认为对象。实际上,它始终是对象(至少在运行时)。在编译期间,您使用的泛型内容只是我们的安全网。将java类编译为字节代码后,编译器将擦除所有泛型内容。因此,您的运行时代码看起来就像您从未使用过泛型。

答案 2 :(得分:0)

它没有“默认”任何东西。原始类型与任何参数化类型不同。

ListQueueListQueue<Object>不同。例如:

ListQueue<String> foo;
ListQueue myQueue = foo; // compiles
ListQueue<Object> myQueue2 = foo; // doesn't compile

但是,就原始类型的方法的参数和返回类型而言,它们都变为非泛型,并且T被减少到上限。