There is a difference. The first one is using raw types, and thus, is less type-safe. For example:
This works, but should not work
class MyClass<T extends Number & Comparable>
{
void use(T t)
{
String s = null;
t.compareTo(s); // Works, but will cause a runtime error
}
}
Whereas this does not work (because it should not work)
class MyClass<T extends Number & Comparable<T>>
{
void use(T t)
{
String s = null;
t.compareTo(s); // Compile-time error
}
}
EDIT: Full code, as requested:
class MyClass<T extends Number & Comparable>
{
void use(T t)
{
String s = "Laziness";
t.compareTo(s); // Works, but will cause a runtime error
}
}
public class MyClassTest
{
public static void main(String[] args)
{
MyClass<Integer> m = new MyClass<Integer>();
Integer integer = new Integer(42);
m.use(integer);
}
}