Java Tutorial/Generics/Bounded Types
Содержание
Bounded Types
The type argument for T must be either Number, or a class derived from Number.
<source lang="java">
class Stats<T extends Number> {
T[] nums; Stats(T[] o) { nums = o; } double average() { double sum = 0.0; for(int i=0; i < nums.length; i++) sum += nums[i].doubleValue(); return sum / nums.length; }
}
public class MainClass {
public static void main(String args[]) { Integer inums[] = { 1, 2, 3, 4, 5 }; Stats<Integer> iob = new Stats<Integer>(inums); double v = iob.average(); System.out.println("iob average is " + v); Double dnums[] = { 1.1, 2.2, 3.3, 4.4, 5.5 }; Stats<Double> dob = new Stats<Double>(dnums); double w = dob.average(); System.out.println("dob average is " + w); }
}</source>
iob average is 3.0 dob average is 3.3
Bounded Wildcards
<source lang="java">
class Two {
int x, y; Two(int a, int b) { x = a; y = b; }
} class Three extends Two {
int z; Three(int a, int b, int c) { super(a, b); z = c; }
} class Four extends Three {
int t; Four(int a, int b, int c, int d) { super(a, b, c); t = d; }
} class Gen<T extends Two> {
T[] coords; Gen(T[] o) { coords = o; }
} // Demonstrate a bounded wildcard. public class MainClass {
static void showTwo(Gen<?> c) { System.out.println("X Y Coordinates:"); for (int i = 0; i < c.coords.length; i++) System.out.println(c.coords[i].x + " " + c.coords[i].y); System.out.println(); } static void showThree(Gen<? extends Three> c) { System.out.println("X Y Z Coordinates:"); for (int i = 0; i < c.coords.length; i++) System.out.println(c.coords[i].x + " " + c.coords[i].y + " " + c.coords[i].z); System.out.println(); } static void showAll(Gen<? extends Four> c) { System.out.println("X Y Z T Coordinates:"); for (int i = 0; i < c.coords.length; i++) System.out.println(c.coords[i].x + " " + c.coords[i].y + " " + c.coords[i].z + " " + c.coords[i].t); System.out.println(); } public static void main(String args[]) { Two td[] = { new Two(0, 0), new Two(7, 9), new Two(18, 4), new Two(-1, -23) }; Gen<Two> tdlocs = new Gen<Two>(td); System.out.println("Contents of tdlocs."); showTwo(tdlocs); // OK, is a TwoD Four fd[] = { new Four(1, 2, 3, 4), new Four(6, 8, 14, 8), new Four(22, 9, 4, 9), new Four(3, -2, -23, 17) }; Gen<Four> fdlocs = new Gen<Four>(fd); System.out.println("Contents of fdlocs."); // These are all OK. showTwo(fdlocs); showThree(fdlocs); showAll(fdlocs); }
}</source>
Contents of tdlocs. X Y Coordinates: 0 0 7 9 18 4 -1 -23 Contents of fdlocs. X Y Coordinates: 1 2 6 8 22 9 3 -2 X Y Z Coordinates: 1 2 3 6 8 14 22 9 4 3 -2 -23 X Y Z T Coordinates: 1 2 3 4 6 8 14 8 22 9 4 9 3 -2 -23 17
Upper/lower bound for a wildcard
Establishing an upper bound for a wildcard
<source lang="java">
<? extends superclass></source>
Using Wildcard Arguments
<source lang="java">
// Use a wildcard. class GenericStats<T extends Number> {
T[] nums; GenericStats(T[] o) { nums = o; } double average() { double sum = 0.0; for(int i=0; i < nums.length; i++){ sum += nums[i].doubleValue(); } return sum / nums.length; } boolean sameAvg(GenericStats<?> ob) { if(average() == ob.average()) return true; return false; }
}
public class MainClass {
public static void main(String args[]) { Integer inums[] = { 1, 2, 3, 4, 5 }; GenericStats<Integer> iob = new GenericStats<Integer>(inums); double v = iob.average(); System.out.println("iob average is " + v); Double dnums[] = { 1.1, 2.2, 3.3, 4.4, 5.5 }; GenericStats<Double> dob = new GenericStats<Double>(dnums); double w = dob.average(); System.out.println("dob average is " + w); Float fnums[] = { 1.0F, 2.0F, 3.0F, 4.0F, 5.0F }; GenericStats<Float> fob = new GenericStats<Float>(fnums); double x = fob.average(); System.out.println("fob average is " + x); System.out.print("Averages of iob and dob "); if(iob.sameAvg(dob)){ System.out.println("are the same."); }else{ System.out.println("differ."); } System.out.print("Averages of iob and fob "); if(iob.sameAvg(fob)){ System.out.println("are the same."); }else{ System.out.println("differ."); } }
}</source>
iob average is 3.0 dob average is 3.3 fob average is 3.0 Averages of iob and dob differ. Averages of iob and fob are the same.