Reputation: 16116
In case you need to pass an argument of an interface type to a method you could use two impl.
Use a bounded type parameter:
public static <I extends InterfaceObj> void isTrue(boolean expression, I interfaceobj) {
if(!expression){
throw new RunTimeException(interfaceobj);
}}
Otherwise you could use the type of interface :
public static void isTrue(boolean expression, InterfaceObj interfaceobj) {
if(!expression){
throw new RunTimeException(interfaceobj);
}
}
Then if I have a class which implements InterfaceObj I could use it in the first and second example so I don't see the difference, advantadges and disadvantages from one or other.
Upvotes: 5
Views: 2266
Reputation: 425448
The difference is that with the first, or typed, version the code in the method can know which exact subtype was passed, but the second version can not.
You would notice the difference more clearly if your methods returned a list of the same type as the parameter. Version one could return List<I>
- a list whose type is the same as the parameter's (sub)type, but version two can only return a List<InterfaceObj>
whose type is the supertype.
Upvotes: 1
Reputation: 4460
I don't see the difference, advantadges and disadvantages from one or other.
I think you forgot about Collections!
If you have a Collection parameter, that's where the real advantage of bounded type parameters comes into play
In this method you can only pass a List which has instatiated like List<InterfaceObj> list = new ArrayList<InterfaceObj>();
public static void processList(List<InterfaceObj> input){
//...
}
but if you use bounded parameterized generic, you can pass all below lists as inputs
List<InterfaceObj> list = new ArrayList<InterfaceObj>();
List<SubInterfaceObj> list = new ArrayList<SubInterfaceObj>();
List<SubSubInterfaceObj> list = new ArrayList<SubSubInterfaceObj>();
public static void processList(List<? extends InterfaceObj> input){
//...
}
Upvotes: 4
Reputation: 131556
From oracle :
There may be times when you want to restrict the types that can be used as type arguments in a parameterized type. For example, a method that operates on numbers might only want to accept instances of Number or its subclasses. This is what bounded type parameters are for.
Functionally, it is exactly the same thing since with a interface as parameter type, it might also only want to accept instances of Number or its subclasses.
Technically, it is slightly different since compiled classes should be different.
In your case, I would prefer use the raw interface type without wildcard since it's less verbose.
It doesn't mean that bounded type parameters in methods are useless.
It can indeed be useful when you use multiple bound type parameters.
Imagine that your method would accept a parameter at the condition that it belongs both to two specified types : InterfaceObj
and OtherInterfaceObj
.
With a interface type, to address this need, you should create another interface which extends these two interfaces and you would use it in your method such as :
public static void isTrue(boolean expression, MyTwoInterfacesObj interfaceobj) {
if (!expression) {
throw new RuntimeException();
}
}
With multiple bound type parameters, you don't need to create an additional interface. You can specify it such as :
public static <I extends InterfaceObj & OtherInterfaceObj> void isTrue(boolean expression, I interfaceobj) {
if (!expression) {
throw new RuntimeException();
}
}
With two interfaces, restricting the parameter type on both of them is a little awkward, imagine with three or four interfaces and multiple possible mixes of them.
Upvotes: 3