Generics upper bound and lower bound in java and generics: in, out android kotlin

Rmvivek
2 min readMar 14, 2022

--

  • 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 type
public 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
}
}

Kotlin Generics: in, out

  1. 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"
}
}

--

--