The differences between the three are mainly related to the checks you get at compile time. Given that generics are designed to protect the user from unsafe use at runtime, critical and fundamental differences between them are rooted there.
AGenericClass<String> declares an instance of a generic class specific to the String type. Any operation performed on this generic type that requires a generic parameter will have this parameter bound to String and will provide type checking and type safety at compile time .
That is, if you have AGenericClass<String> a = new AGenericClass<>(); and you are trying to call a.setSubject(3) , Java will not allow compilation of the application since the types do not match.
AGenericClass<?> Declares an instance of a generic class with unknown types. Formally ? is a wildcard in which it can be of any type, which is great if you want to extract elements from it, but not very well if you want to add elements from it.
Cause? AGenericClass<?> Actually AGenericClass<? extends Object> AGenericClass<? extends Object> , and this is important because of the principle of entry and exit . Generally (although this is not a strict guarantee), anything in common with extends implies a read-only operation.
As I said, itβs ok to read, because you are guaranteed a class that is no more than Object , but you cannot write to it, since you do not know and cannot guarantee which object you add to it from any given call.
AGenericClass without type declarations is a raw type. You can read more about them here , but you know that they exist for reasons related to outdated compatibility. If your code uses raw types, you lose compile-time checking , and your code can cause a meta call to ClassCastException at runtime, which is much more difficult to debug, diagnose and resolve.
source share