forked from BruceEckel/OnJava8-Examples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTrash.java
More file actions
91 lines (90 loc) · 2.74 KB
/
Trash.java
File metadata and controls
91 lines (90 loc) · 2.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// patterns/trash/Trash.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://mindviewinc.com/Books/OnJava/ for more book information.
// Base class for Trash recycling examples
package patterns.trash;
import java.util.*;
import java.lang.reflect.*;
public abstract class Trash {
private double weight;
public Trash(double wt) { weight = wt; }
public Trash() {}
public abstract double value();
public double weight() { return weight; }
// Sums the value of Trash in a bin:
static double val;
public static <T extends Trash>
void sumValue(List<? extends T> bin) {
val = 0.0f;
bin.forEach( t -> {
val += t.weight() * t.value();
System.out.println("weight of " +
// RTTI gets type information
// about the class:
t.getClass().getName() +
" = " + t.weight());
});
System.out.println("Total value = " + val);
}
@Override
public String toString() {
// Print correct subclass name:
return getClass().getName() +
" w:" + weight() + " v:" +
String.format("%.2f", value());
}
// Remainder of class supports dynamic creation:
public static class CannotCreateTrashException
extends RuntimeException {
public CannotCreateTrashException(Exception why) {
super(why);
}
}
public static class TrashClassNotFoundException
extends RuntimeException {
public TrashClassNotFoundException(Exception why) {
super(why);
}
}
public static class Info {
public String id;
public double data;
public Info(String name, double data) {
id = name;
this.data = data;
}
}
private static List<Class> trashTypes =
new ArrayList<>();
@SuppressWarnings("unchecked")
public static <T extends Trash> T factory(Info info) {
for(Class trashType : trashTypes) {
// Determine the type and create one:
if(trashType.getName().contains(info.id)) {
try {
// Get the dynamic constructor method
// that takes a double argument:
Constructor ctor = trashType.getConstructor(
double.class);
// Call the constructor to create a
// new object:
return (T)ctor.newInstance(info.data);
} catch(Exception e) {
throw new CannotCreateTrashException(e);
}
}
}
// The necessary Class was not in the list. Try to
// load it, but it must be in your class path!
try {
System.out.println("Loading " + info.id);
trashTypes.add(Class.forName(info.id));
} catch(Exception e) {
throw new TrashClassNotFoundException(e);
}
// Loaded successfully. Recursive call
// should work this time:
return factory(info);
}
}