Java/Generics/Constraints
Содержание
Bounded Wildcard arguments.
<source lang="java">
class TwoD {
int x, y; TwoD(int a, int b) { x = a; y = b; }
} class ThreeD extends TwoD {
int z; ThreeD(int a, int b, int c) { super(a, b); z = c; }
} class FourD extends ThreeD {
int t; FourD(int a, int b, int c, int d) { super(a, b, c); t = d; }
} class Coords<T extends TwoD> {
T[] coords; Coords(T[] o) { coords = o; }
} class BoundedWildcard {
static void showXY(Coords<?> 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 showXYZ(Coords<? extends ThreeD> 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(Coords<? extends FourD> 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[]) { TwoD td[] = { new TwoD(0, 0), new TwoD(7, 9), new TwoD(18, 4), new TwoD(-1, -23) }; Coords<TwoD> tdlocs = new Coords<TwoD>(td); System.out.println("Contents of tdlocs."); showXY(tdlocs); // OK, is a TwoD FourD fd[] = { new FourD(1, 2, 3, 4), new FourD(6, 8, 14, 8), new FourD(22, 9, 4, 9), new FourD(3, -2, -23, 17) }; Coords<FourD> fdlocs = new Coords<FourD>(fd); System.out.println("Contents of fdlocs."); // These are all OK. showXY(fdlocs); showXYZ(fdlocs); showAll(fdlocs); }
}
</source>
Generic cast
<source lang="java">
/*
* Copyright (C) 2001-2003 Colin Bell * colbell@users.sourceforge.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
import java.io.*; import java.text.NumberFormat; import java.util.regex.Matcher; import java.util.regex.Pattern; /**
* General purpose utilities functions. * * @author */
public class Utilities {
/** * This is taken from Eammon McManus" blog: * http://weblogs.java.net/blog/emcmanus/archive/2007/03/getting_rid_of.html This prevents you from having * to place SuppressWarnings throughout your code. * * @param <T> * the return type to cast the object to * @param x * the object to cast. * @return a type-casted version of the specified object. */ @SuppressWarnings("unchecked") public static <T> T cast(Object x) { return (T) x; }
}
</source>
Java generic: Bounded Wildcard arguments
<source lang="java">
/* Java 2, v5.0 (Tiger) New Features by Herbert Schildt ISBN: 0072258543 Publisher: McGraw-Hill/Osborne, 2004
- /
// Two-dimensional coordinates. class TwoD {
int x, y; TwoD(int a, int b) { x = a; y = b; }
}
// Three-dimensional coordinates. class ThreeD extends TwoD {
int z; ThreeD(int a, int b, int c) { super(a, b); z = c; }
}
// Four-dimensional coordinates. class FourD extends ThreeD {
int t; FourD(int a, int b, int c, int d) { super(a, b, c); t = d; }
}
// This class holds an array of coordinate objects. class Coords<T extends TwoD> {
T[] coords; Coords(T[] o) { coords = o; }
}
// Demonstrate a bounded wildcard. public class BoundedWildcard {
static void showXY(Coords<?> 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 showXYZ(Coords<? extends ThreeD> 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(Coords<? extends FourD> 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[]) { TwoD td[] = { new TwoD(0, 0), new TwoD(7, 9), new TwoD(18, 4), new TwoD(-1, -23) }; Coords<TwoD> tdlocs = new Coords<TwoD>(td); System.out.println("Contents of tdlocs."); showXY(tdlocs); // OK, is a TwoD
// showXYZ(tdlocs); // Error, not a ThreeD // showAll(tdlocs); // Erorr, not a FourD
// Now, create some FourD objects. FourD fd[] = { new FourD(1, 2, 3, 4), new FourD(6, 8, 14, 8), new FourD(22, 9, 4, 9), new FourD(3, -2, -23, 17) }; Coords<FourD> fdlocs = new Coords<FourD>(fd); System.out.println("Contents of fdlocs."); // These are all OK. showXY(fdlocs); showXYZ(fdlocs); showAll(fdlocs); }
}
</source>
Java generic: Use a wildcard.
<source lang="java">
/* Java 2, v5.0 (Tiger) New Features by Herbert Schildt ISBN: 0072258543 Publisher: McGraw-Hill/Osborne, 2004
- /
class Stats<T extends Number> {
T[] nums; // array of Number or subclass // Pass the constructor a reference to // an array of type Number or subclass. Stats(T[] o) { nums = o; } // Return type double in all cases. double average() { double sum = 0.0; for(int i=0; i < nums.length; i++) sum += nums[i].doubleValue(); return sum / nums.length; } // Determine if two averages are the same. // Notice the use of the wildcard. boolean sameAvg(Stats<?> ob) { if(average() == ob.average()) return true; return false; }
}
// Demonstrate wildcard. public class WildcardDemo {
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); Float fnums[] = { 1.0F, 2.0F, 3.0F, 4.0F, 5.0F }; Stats<Float> fob = new Stats<Float>(fnums); double x = fob.average(); System.out.println("fob average is " + x); // See which arrays have same average. 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>
Use a wildcard.
<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; } boolean sameAvg(Stats<?> ob) { if (average() == ob.average()) return true; return false; }
} class WildcardDemo {
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); Float fnums[] = { 1.0F, 2.0F, 3.0F, 4.0F, 5.0F }; Stats<Float> fob = new Stats<Float>(fnums); double x = fob.average(); System.out.println("fob average is " + x); // See which arrays have same average. 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>