Skip to content

Commit 63450d1

Browse files
author
Arpit Bhardwaj
committed
Bounded and and unbounded generic types
1 parent 0040324 commit 63450d1

7 files changed

Lines changed: 299 additions & 1 deletion

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.ab.generics.model;
2+
3+
public class Employee extends Person {
4+
public Employee(String name, int age) {
5+
super(name, age);
6+
}
7+
8+
@Override
9+
public String toString() {
10+
return "Employee{" +
11+
"name='" + getName() + '\'' +
12+
", age=" + getAge() +
13+
'}';
14+
}
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.ab.generics.model;
2+
3+
public class Partner extends Person {
4+
public Partner(String name, int age) {
5+
super(name, age);
6+
}
7+
8+
@Override
9+
public String toString() {
10+
return "Partner{" +
11+
"name='" + getName() + '\'' +
12+
", age=" + getAge() +
13+
'}';
14+
}
15+
}

src/main/java/com/ab/generics/model/Person.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import java.util.Objects;
44

5-
public final class Person {
5+
public class Person {
66
private final String name;
77
private final int age;
88

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.ab.generics.wildcard;
2+
3+
import com.ab.generics.model.Person;
4+
5+
import java.io.*;
6+
import java.lang.reflect.Constructor;
7+
import java.lang.reflect.InvocationTargetException;
8+
import java.util.List;
9+
10+
public class PersonLoader {
11+
private final RandomAccessFile file;
12+
13+
public PersonLoader(final File file) throws FileNotFoundException {
14+
this.file = new RandomAccessFile(file,"rw");
15+
}
16+
public Person load() throws ClassNotFoundException {
17+
/*int age = file.readInt();
18+
String name = file.readUTF();
19+
Person person = new Person(name, age);*/
20+
21+
/*FileInputStream fis = new FileInputStream(String.valueOf(file));
22+
ObjectInputStream iis = new ObjectInputStream(new BufferedInputStream(fis));
23+
Object obj = iis.readObject();
24+
return (Person) obj;*/
25+
26+
try {
27+
final String className = file.readUTF();
28+
final String personName = file.readUTF();
29+
final int age = file.readInt();
30+
final Class<?> personClass = Class.forName(className);
31+
final Constructor<?> personClassConstructor = personClass.getConstructor(String.class, int.class);
32+
return (Person) personClassConstructor.newInstance(personName,age);
33+
}
34+
catch (IOException e) {
35+
return null;
36+
//e.printStackTrace();
37+
}
38+
catch (NoSuchMethodException e) {
39+
e.printStackTrace();
40+
} catch (IllegalAccessException e) {
41+
e.printStackTrace();
42+
} catch (InstantiationException e) {
43+
e.printStackTrace();
44+
} catch (InvocationTargetException e) {
45+
e.printStackTrace();
46+
}
47+
return null;
48+
}
49+
50+
/*public void loadAll(List<Person> persons) throws ClassNotFoundException {
51+
Person person;
52+
53+
while ((person = load()) != null){
54+
persons.add(person);
55+
}
56+
}*/
57+
58+
//when putting things in list use super
59+
//Contra variance
60+
public void loadAll(List<? super Person> persons) throws ClassNotFoundException {
61+
Person person;
62+
63+
while ((person = load()) != null){
64+
persons.add(person);
65+
}
66+
}
67+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.ab.generics.wildcard;
2+
3+
import com.ab.generics.model.Person;
4+
5+
import java.io.File;
6+
import java.io.FileNotFoundException;
7+
import java.io.IOException;
8+
import java.io.RandomAccessFile;
9+
import java.util.List;
10+
11+
public class PersonSaver {
12+
private final RandomAccessFile file;
13+
14+
public PersonSaver(final File file) throws FileNotFoundException {
15+
this.file = new RandomAccessFile(file,"rw");
16+
}
17+
18+
public void save(Person person) throws IOException {
19+
20+
file.writeUTF(person.getClass().getName());
21+
file.writeUTF(person.getName());
22+
file.writeInt(person.getAge());
23+
}
24+
25+
public void saveAll(Person[] persons) throws IOException {
26+
27+
for (Person person: persons) {
28+
save(person);
29+
}
30+
}
31+
32+
//while getting or extract things from list use extends
33+
//Covariance
34+
public void saveAll(List<? extends Person> persons) throws IOException {
35+
for (Person person: persons) {
36+
save(person);
37+
}
38+
}
39+
40+
//this way also can be done by passing T in function but it becomes cluttered
41+
/*public <T extends Person> void saveAll(List<T> persons) throws IOException {
42+
for (T person: persons) {
43+
save(person);
44+
}
45+
}*/
46+
47+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.ab.generics.wildcard;
2+
3+
import com.ab.generics.model.Person;
4+
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
8+
/**
9+
* @author Arpit Bhardwaj
10+
*/
11+
public class Unbounded {
12+
public static void main(String[] args) {
13+
List<Object> objects = new ArrayList<>();
14+
objects.add(new Object());
15+
objects.add(new Person("Nish", 28));
16+
System.out.println(objects);
17+
18+
//Compile time error
19+
/*List<?> objects2 = new ArrayList<>();
20+
objects2.add(new Object());
21+
objects2.add(new Person("Nish", 28));
22+
System.out.println(objects2);*/
23+
24+
//As adding use contra variance
25+
List<? super Object> objects2 = new ArrayList<>();
26+
objects2.add(new Object());
27+
objects2.add(new Person("Nish", 28));
28+
System.out.println(objects2);
29+
30+
//the only value pass through ? is null
31+
List<?> objects3 = new ArrayList<>();
32+
objects3.add(null);
33+
System.out.println(objects3);
34+
}
35+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package com.ab.generics.wildcard;
2+
3+
import com.ab.generics.model.Employee;
4+
import com.ab.generics.model.Partner;
5+
import com.ab.generics.model.Person;
6+
import org.junit.After;
7+
import org.junit.Before;
8+
import org.junit.Test;
9+
10+
import java.io.File;
11+
import java.io.IOException;
12+
import java.util.ArrayList;
13+
import java.util.List;
14+
15+
import static org.junit.Assert.*;
16+
17+
public class PersonStorageTest {
18+
private Partner donDrapper = new Partner("Don Drapper", 89);
19+
private Employee peggyOlson = new Employee("Peggy Olson", 65);
20+
private Partner bertCooper = new Partner("Bert Cooper", 100);
21+
22+
private File file;
23+
private PersonSaver saver;
24+
private PersonLoader loader;
25+
26+
@Test
27+
public void saveAndLoadsPerson() throws IOException, ClassNotFoundException {
28+
/*Person person = new Person("bob", 20);
29+
saver.save(person);
30+
assertEquals(person, loader.load());*/
31+
32+
saver.save(donDrapper);
33+
assertEquals(donDrapper,loader.load());
34+
35+
saver.save(peggyOlson);
36+
assertEquals(peggyOlson,loader.load());
37+
}
38+
39+
@Test
40+
public void saveAndLoadsArraysOfPeople() throws IOException, ClassNotFoundException {
41+
/*Person[] person = new Person[2];
42+
person[0] = donDrapper;
43+
person[1] = bertCooper;
44+
45+
saver.saveAll(person);*/
46+
47+
//Arrays are covariants
48+
/*Partner[] partners = new Partner[2];
49+
Person[] persons = partners;
50+
partners[0] = donDrapper;
51+
partners[1] = bertCooper;
52+
53+
saver.saveAll(partners);*/
54+
55+
/*Partner[] partners = new Partner[2];
56+
Person[] persons = partners;
57+
persons[0] = donDrapper;
58+
persons[1] = bertCooper;
59+
60+
saver.saveAll(persons);*/
61+
62+
//Arrays are type unsafe leads to ArrayStoreException
63+
/*Employee[] employees = new Employee[2];
64+
Person[] persons = employees;
65+
persons[0] = donDrapper;
66+
persons[1] = bertCooper;
67+
68+
saver.saveAll(persons);*/
69+
70+
/*List<Person> persons = new ArrayList<>();
71+
persons.add(donDrapper);
72+
persons.add(bertCooper);
73+
74+
saver.saveAll(persons);*/
75+
76+
//Leads to compile time error in order to remove use upper bounded wildcards in saveAll method
77+
List<Partner> persons = new ArrayList<>();
78+
persons.add(donDrapper);
79+
persons.add(bertCooper);
80+
81+
saver.saveAll(persons);
82+
83+
84+
assertEquals(donDrapper, loader.load());
85+
assertEquals(bertCooper,loader.load());
86+
}
87+
88+
@Test
89+
public void loadListsOfPeople() throws Exception{
90+
saver.save(donDrapper);
91+
saver.save(peggyOlson);
92+
93+
/*List<Person> persons = new ArrayList<>();
94+
loader.loadAll(persons);*/
95+
96+
/*List<Partner> partners = new ArrayList<>();
97+
loader.loadAll(partners);*/
98+
99+
List<Object> persons = new ArrayList<>();
100+
loader.loadAll(persons);
101+
102+
assertEquals(donDrapper, persons.get(0));
103+
assertEquals(peggyOlson,persons.get(1));
104+
}
105+
106+
@Before
107+
public void setUp() throws Exception {
108+
file = File.createTempFile("tmp", "people");
109+
saver = new PersonSaver(file);
110+
loader = new PersonLoader(file);
111+
}
112+
113+
@After
114+
public void tearDown() throws Exception {
115+
if (file.exists()){
116+
file.delete();
117+
}
118+
}
119+
}

0 commit comments

Comments
 (0)