7. Generics
erasure
bridge method
7.1. Basic generic
1public static class Record<T> {
2 T[] data;
3
4 public Record(T[] data) {
5 this.data = data;
6 }
7
8 @Override
9 public String toString() {
10 StringBuilder sb = new StringBuilder();
11 for (int i = 0; i < data.length; i++) {
12 sb.append(data[i]);
13 if (i < data.length - 1) {
14 sb.append(',');
15 }
16 }
17 return sb.toString();
18 }
19}
1var record1 = new Record<Integer>(new Integer[] { 1, 2, 3});
2var record2 = new Record<Double>(new Double[] { 1d, 2d, 3d });
3
4System.out.println(record1);
5System.out.println(record2);
7.2. Generic with two types
1public static class Record<I, T> {
2 I id;
3 T[] data;
4
5 public Record(I id, T[] data) {
6 this.id = id;
7 this.data = data;
8 }
9
10 @Override
11 public String toString() {
12 StringBuilder sb = new StringBuilder();
13 sb.append(id).append(':');
14
15 for (int i = 0; i < data.length; i++) {
16 sb.append(data[i]);
17 if (i < data.length - 1) {
18 sb.append(',');
19 }
20 }
21
22 return sb.toString();
23 }
24}
1var record1 = new Record<Integer, Integer>(0, new Integer[] { 1, 2, 3});
2var record2 = new Record<String, Double>("a", new Double[] { 1d, 2d, 3d });
3
4System.out.println(record1);
5System.out.println(record2);
7.3. Generic with bounded type
1public static class Data<T extends Number> {
2 private T[] data;
3
4 public Data(T[] data) {
5 this.data = data;
6 }
7
8 public double getSum() {
9 double sum = 0.0d;
10 for (T item : data) {
11 sum += item.doubleValue();
12 }
13 return sum;
14 }
15}
1var data1 = new Data<Integer>(new Integer[] { 1, 2, 3, 4});
2var data2 = new Data<Double>(new Double[] { 5d, 6d, 7d, 8d});
3
4System.out.println(data1.getSum());
5System.out.println(data2.getSum());
7.4. Generic with wild card
1public static class Data<T extends Number> {
2 private T[] data;
3
4 public Data(T[] data) {
5 this.data = data;
6 }
7
8 public double getSum() {
9 double sum = 0.0d;
10 for (T item : data) {
11 sum += item.doubleValue();
12 }
13 return sum;
14 }
15
16 public T[] getData() {
17 return data;
18 }
19
20 public boolean isSameLength(Data<?> that) {
21 return this.data.length == that.data.length;
22 }
23}
1var data1 = new Data<Integer>(new Integer[] { 1, 2, 3, 4, 9, 10});
2var data2 = new Data<Double>(new Double[] { 5d, 6d, 7d, 8d});
3
4System.out.println(data1.isSameLength(data2));
7.5. Generic interface
1public interface Pet<I> {
2 I getId();
3 String getName();
4 String makeNoise();
5}
6
7public static class PetImpl implements Pet<Integer> {
8 private final Integer id;
9 private final String name;
10 private final String noise;
11
12 public PetImpl(Integer id, String name, String noise) {
13 this.id = id;
14 this.name = name;
15 this.noise = noise;
16 }
17
18 @Override
19 public Integer getId() {
20 return id;
21 }
22
23 @Override
24 public String getName() {
25 return name;
26 }
27
28 @Override
29 public String makeNoise() {
30 return noise;
31 }
32}
1var dog1 = new PetImpl(0, "Max", "woof!");
2var dog2 = new PetImpl(0, "Dax", "bark!");
3var dogs = new Pet[] { dog1, dog2 };
4
5for (Pet pet : dogs) {
6 System.out.println(pet.getId() + ": " + pet.getName() + " says " + pet.makeNoise());
7}