Reputation: 169
I am having a basic java question as I recently decided to dig into the language (I have been working exclusively with C++ for a long time and decided to expand my horizons a bit).
Assuming that I have a class called BankAccount and I try to create and object in my main, what is the difference between:
Class baCls = BankAccount.class;
and
Class<BankAccount> baCls = BankAccount.class;
What does the baCls hold in each of the cases and what is the compiler output?
Upvotes: 0
Views: 52
Reputation: 140319
Peter Lawrey's answer addresses your specific question, but I think that it is missing an important fact that the second case provides additional, invaluable information to the compiler.
The difference is that the first case is a raw type:
Class baCls = BankAccount.class;
^ Missing type parameters.
There are (at least) two consequences of this (which are general consequences of using raw types):
You can't invoke producer methods like Class.nextInstance()
method and assign the result to a reference of type BankAccount
without a cast:
Class baCls = BankAccount.class;
BankAccount instance = (BankAccount) baCls.newInstance(/* required args */);
However, you don't need the cast in the second case, because it is known that the nextInstance
method will return an instance of BankAccount
:
Class<BankAccount> baClsSafe = BankAccount.class;
BankAccount instance = baCls.newInstance(/* req args */);
You lose type safety if you are putting these into collections. For instance:
Class baCls = BankAccount.class;
List<Class<String>> list = new ArrayList<>();
list.add(baCls); // Compiles fine.
This appears fine, but you get a runtime exception later if you assume that the elements in the list are of the correct type:
for (Class<String> clazz : list) {
String instance = clazz.newInstance(); // ClassCastException.
}
because instance
is actually an instance of BankAccount
(assuming that has a zero-args constructor).
In the second case, you would never be able to add this item to the list in the first place:
Class<BankAccount> baCls = BankAccount.class;
List<Class<String>> list = new ArrayList<>();
list.add(baCls); // Compiler error.
I would recommend that you read up about raw types, e.g. in the generics tutorial, as well as in Effective Java 2nd Ed Item 23 "Don't use raw types in new code".
Upvotes: 0
Reputation: 533492
In both cases baCls
is a reference to the class BankAccount
The generic adds a compile time check but has no impact at runtime.
You can see the bytecode generated if you use javap -c -p
or a byte code viewer in your IDE.
Upvotes: 4