Specifically, if I return a filled ArrayList
do I have to return the type with it such as ArrayList<modNode>
? To add onto this, if i'm using a generic typing for a custom link list that uses the <T>
tag would I have to return ArrayList<modNode<T>>
? Just a little curious on the properties of ArrayLists containing generic objects... Thanks in advance!
- 23
- 1
- 7
-
It's not quite clear what you're asking. Can you offer an example of what you mean? – Kevin Anderson Aug 10 '18 at 03:21
-
Can you please share the code and the problem you are facing? – Dinesh Aug 10 '18 at 03:22
-
If you turn on all compiler warnings, the compiler will tell you when you are improperly returning a raw type or any other unsafe type. It’s good practice in general to turn on all the warnings. – VGR Aug 10 '18 at 04:55
2 Answers
Let's say you have a method that returns an ArrayList
of String
objects:
public ArrayList<String> foo() {
ArrayList<String> list = new ArrayList<>();
// ... fill list ...
return list;
}
This is how you would normally1 declare the method in Java 5+ (since the addition of generics). But you don't have to do this. You could declare the method as:
public ArrayList foo() {
// ... code ...
return list;
}
This would mean you are using raw types. Unless you are interacting with a legacy (pre Java 5) library/application you never want to use raw types. The reason is because a raw type is (nearly?) equivalent to returning ArrayList<Object>
. You've just lost all type safety given by generics. The reason for generics is to provide compile-time2 type checks so you don't accidentally use the wrong types. For instance, you could now add a Dog
to the ArrayList
returned by foo
even though you intended it to only contain String
objects. Also, code using the returned ArrayList
has no guarantee that there will only be String
objects inside the ArrayList
which can result in all sorts of headaches.
You could get around raw types by casting:
String element = (String) foo().get(0);
However, that's basically what generic code compiles down to anyway; except you no longer have compile-time safety.
If the element type is also generic then yes you would want to return that information as well. Let's say you return an ArrayList
of Supplier
objects instead. It will be each Supplier
that returns the needed String
objects.
public ArrayList<Supplier<String>> foo() {
// ... code ...
}
It's important you give the Supplier
's generic signature here so you can do things like:
for (Supplier<String> sup : foo()) {
String str = sup.get();
// .. do something with "str" ...
}
If you returned ArrayList<Supplier>
then each Supplier.get()
would return an Object
. You've lost all type safety again.
1. You would actually, in virtually all cases, want to return List
rather than ArrayList
. It's best to program to an interface.
2. It only works at compile-time due to type erasure. Also see this.
- 25,955
- 5
- 33
- 58
The type parameter <T>
depends on the actual Type Parameter you supply to Generic Type. For example:-
List<String> names = new ArrayList<>();
String
is the actual type parameter of parameterized type List<String>
. Behind the scene compiler did casting on each elements automatically. So you can safely expect get
method will return String
type.
The modNode
class is generic type. Then caller has to declare what is the actual type parameter. It could be String
, type that extends Node
or whatever. Example below:-
List<modeNode<String>> modeNodes = new ArrayList<>();
However your ArrayList<modNode<T>>
actual type parameter is already modeNode
. Hence get
method will probably returns some kind parameterized type modeNode<T>
. Ex:-
List<modeNode<String>> modeNodes = new ArrayList<>();
....
modeNode<String> mn = modeNodes.get(0);
Notes:-
** Rename modNode
type class name to ModNode
to follow Java convention. Class name must start with Capital letter.
ModeNode<Node> mn = ModeNode.getInstance();
//More readable due to following naming convention.
List<ModeNode<Node>> mns = new ArrayList<>();
** It is preferable to declare as interface type List
than concrete type ArrayList
. Unless if you want to use specific ArrayList
behaviour implementation.
- 363
- 2
- 9