Generics upper bound and lower bound in java and generics: in, out android kotlin
- Unbounded Wildcards: List<?> represents a list of unknown type
- Upper Bounded Wildcards: List<? extends Number> represents a list of Number or its sub-types such as Integer and Double
- Lower Bounded Wildcards: List<? super Integer> represents a list of Integer or its super-types Number and object.
Eg:
We can declare sample classes
interface Madurai { }
abstract class Hosur implements Madurai { }
abstract class Arni {}
class Chennai extends Arni { }
class Vellore extends Chennai implements Madurai {}
class Erode extends Vellore { }
class Salem extends Arni {}
We can Define List<? super T>
and List<? extends T>
static void add(List<? super Vellore> list) {do logic}->access only base generic type
static void print(List<? extends Chennai> list) {do logic}->access only drived generic typepublic class City {
static void add(List<? super Vellore> list) {do logic}
static void print(List<? extends Chennai> list) {do logic}
public static void main(String[] args) {
List<Object> list0 = new ArrayList<Object>();
List<Arni> list = new ArrayList<Arni>();
List<Chennai> list1 = new ArrayList<Chennai>();
List<Vellore> list2 = new ArrayList<Vellore>();
List<Madurai> list3 = new ArrayList<Madurai>();
List<Salem> list4 = new ArrayList<Salem>();
List<Erode> list5 = new ArrayList<Erode>();
List<Hosur> list6 = new ArrayList<Hosur>();
add(list0);
add(list);
add(list1);
add(list2);
add(list3);
add(list4);//err
add(list5);//err
add(list6);//err
print(list);//err
print(list0);//err
print(list1);
print(list2);
print(list3);//err
print(list4);//err
print(list5);
print(list6);//err
}
}
- Array<in String > corresponds to Java Array<? Super String>
means we can pass an array of charsequence or an array of object
2. Array<out Any> corresponds to Java Array<? extends Object>
for the example
in->assing the value, set the value , write the value
// generic interface
interface Road<in R>{
fun setCity(points:R)
}//class implement from interfaceclass RoadSerial():Road<Int>
{
override fun setCity(points: Int) {
val roadNo=points
}
}
out-> fetch the value, return the value, read the value
interface City<out T>{
fun getCity():T
}class Area():City<String>
{
override fun getCity(): String {
return "Arni"
}
}
Generics combine of in and out
interface Country<out R,in M>{
fun setCity(points:M)
fun getCity():R
}class CityDetail:Country<String,Int>
{
override fun setCity(points: Int) {
val roadNo=points
} override fun getCity(): String {
return "Arni"
}
}