本篇文章简单介绍Java中的泛型,以及它为什么会被设计出来。
泛型时在JDK1.5的时候引入的,它的作用就如它的名字一样——一代多。
泛型:类中操作的属性或方法的参数类型不在定义时声明,而是在使用时动态设置。
假设我们要设计一个表示坐标的类--Point,它有两个属性x和y。
①x,y都是int型的
public class GenericTest {
public static void main(String[] args) {
Point point = new Point();
point.setX(20);
point.setY(15);
int x = (int)point.getX();
int y = (int)point.getY();
System.out.println("输出X坐标是:" + x);
System.out.println("输出Y坐标是:" + y);
}
}
class Point{
int x;
int y;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
②x,y是double型的
public class GenericTest {
public static void main(String[] args) {
Point point = new Point();
point.setX(20.3);
point.setY(15.5);
double x = (double)point.getX();
double y = (double)point.getY();
System.out.println("输出X坐标是:" + x);
System.out.println("输出Y坐标是:" + y);
}
}
class Point{
double x;
double y;
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
}
③x,y是String型的
public class GenericTest {
public static void main(String[] args) {
Point point = new Point();
point.setX("20.3");
point.setY("15.5");
String x = (String)point.getX();
String y = (String)point.getY();
System.out.println("输出X坐标是:" + x);
System.out.println("输出Y坐标是:" + y);
}
}
class Point{
String x;
String y;
public String getX() {
return x;
}
public void setX(String x) {
this.x = x;
}
public String getY() {
return y;
}
public void setY(String y) {
this.y = y;
}
}
三种方式都是可以正常运行并且输出相应的x,y坐标的。但是我们定义的Point类每个都只能定义一种x,y的数据类型,不够万能。所以,我们考虑使用超类Object。
使用Object设计Point类
public class GenericTest {
public static void main(String[] args) {
Point point = new Point();
// point.setX("20.3");//String型
// point.setY("15.5");
// point.setX(20);//int型
// point.setY(15);
point.setX(20.3);//double型
point.setY(15.5);
double x = (double)point.getX();
double y = (double)point.getY();
System.out.println("输出X坐标是:" + x);
System.out.println("输出Y坐标是:" + y);
}
}
class Point{
Object x;
Object y;
public Object getX() {
return x;
}
public void setX(Object x) {
this.x = x;
}
public Object getY() {
return y;
}
public void setY(Object y) {
this.y = y;
}
}
没问题,设计一个Point就可以表示三种数据类型了。但是,上面的程序还是会有问题的!!!之所以可以Object来定义Point类,是基于Java的自动装箱机制:int/double装成Integer/Double,向上转型为Object,String转型为Object。而程序的问题就是在这里,一旦我们的程序需要一个int型的x坐标,一个String类型的y坐标就会出现问题。
public class GenericTest {
public static void main(String[] args) {
Point point = new Point();
point.setX(10);//String型
point.setY("15.5");
// point.setX(20);//int型
// point.setY(15);
// point.setX(20.3);//double型
// point.setY(15.5);
String x = (String)point.getX();//这里是13行
String y = (String)point.getY();
System.out.println("输出X坐标是:" + x);
System.out.println("输出Y坐标是:" + y);
}
}
class Point{
Object x;
Object y;
public Object getX() {
return x;
}
public void setX(Object x) {
this.x = x;
}
public Object getY() {
return y;
}
public void setY(Object y) {
this.y = y;
}
}
输出报错:Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at com.zsf.GenericTest.main(GenericTest.java:13)
如何解决这个问题呢?使用泛型。
public class GenericTest {
public static void main(String[] args) {
Point<Double> point = new Point<>();
point.setX(20.3);
point.setY(15.5);
double x = point.getX();
double y = point.getY();
System.out.println("输出X坐标是:" + x);
System.out.println("输出Y坐标是:" + y);
}
}
class Point<P>{
P x;
P y;
public P getX() {
return x;
}
public void setX(P x) {
this.x = x;
}
public P getY() {
return y;
}
public void setY(P y) {
this.y = y;
}
}
搞定。