java学习之路-----泛型---

来源:互联网 发布:linux 复制文件覆盖 编辑:程序博客网 时间:2024/05/21 14:49
1.泛型的引入:

为什么要用泛型?

          比如现在要设计一个坐标的方法

                    坐标有几种表示方法:     
                                                  1.整数:x=20,y=20
                                                  2.小数:x=20.2,y=20.2
                                                  3.字符串:x=东京180,y="北纬210"

看到这里我们是不是在想,要建立一个point类是,里面定义一个方法,来接收这三种数据,但是数据有三种,那么就只有用Object来接收了。因为Object可以接收任何数据,发生向上转型。。。
          

     实现的思路:
          


     代码:
//整数接收
class Point{
      private Object x;
     
      private 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;
     }
     
}


public class PointTest {
     
      public static void main(String[] args) {
          Point point= new Point();
           //整数接收
          point.setX(20);
          
          point.setY(20);
          
           int x=(Integer)point.getX();
          
           int y=(Integer)point.getY();
          
          System. out .println("x坐标:" +x);
          
          System. out .println("y坐标:" +y);
     }
}

结果:
x坐标:20
y坐标:20


//小数接收

class Point{
      private Object x;
     
      private 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;
     }
     
     
     
}


public class PointTest {
     
      public static void main(String[] args) {
          Point point= new Point();
           //整数接收
          point.setX(20.2);
          
          point.setY(20.2);
          
           double x=(Double)point.getX();
          
           double y=(Double)point.getY();
          
          System. out .println("x坐标:" +x);
          
          System. out .println("y坐标:" +y);
     }
}

结果:

x坐标:20.2
y坐标:20.2


//字符转接收

class Point{
      private Object x;
     
      private 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;
     }
     
     
     
}


public class PointTest {
     
      public static void main(String[] args ) {
          Point point= new Point();
           //整数接收
          point.setX( "东经120" );
          
          point.setY( "北纬60" );
          
          String x=(String)point.getX();
          
          String y=(String)point.getY();
          
          System. out .println("x坐标:" +x);
          
          System. out .println("y坐标:" +y);
     }
}
结果:
x坐标:东经120
y坐标:北纬60

好像这样是实现了我们想要的结果,那么来看看这段代码:


class Point{
      private Object x;
     
      private 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;
     }
     
     
     
}


public class PointTest {
     
      public static void main(String[] args) {
          Point point= new Point();
           //整数接收
          point.setX(123);
          
          point.setY( "北纬60" );//这里是用Object来接收的,所以可以接收任何类型
          
           int x=(Integer)point.getX();
          
           int y=(Integer)point.getY();
          
          System. out .println("x坐标:" +x);
          
          System. out .println("y坐标:" +y);
     }
}

结果:
Exception in thread "main" java.lang.ClassCastException : java.lang.String cannot be cast to java.lang.Integer
     at test.PointTest.main( PointTest.java:42 )
所以,这样为们才有了现在的泛型


泛型代码:


class Point1<T>{//声明一个泛型类
          
      private  T  var; //声明一个泛型变量
     
      private T  Yar;

      public T getVar() {
           return var ;
     }

      public void setVar(T var) {
           this .var = var;
     }

      public T getYar() {
           return Yar ;
     }

      public void setYar(T yar) {
           Yar = yar;
     }
     
     
}


public class PointTest1 {
     
           public static void main(String[] args) {
              Point1<Object> point= new Point1<Object>();
              point.setVar(20);
              point.setYar( "北纬" );
                   System. out .println("x坐标" +point.getVar());
                   System. out .println("y坐标" +point.getYar());
              
          }

}

结果:

x坐标20
y坐标北纬

2.泛型的构造方法

class Point1<T>{//声明一个泛型类
          
      private  T  var; //声明一个泛型变量
     
      private T  Yar;

      public T getVar() {
           return var ;
     }

     
     
      public Point1(T var, T yar) {
           this .var = var;
           Yar = yar;
     }



      public void setVar(T var) {
           this .var = var;
     }

      public T getYar() {
           return Yar ;
     }

      public void setYar(T yar) {
           Yar = yar;
     }
     
     
}


public class PointTest1 {
     
           public static void main(String[] args) {
              Point1<Object> point= new Point1<Object>(20,"北纬" );
               //point.setVar(20);
           //   Point1<String> point1=new Point1<String>();
           //   point.setYar("北纬");
                   System. out .println("x坐标" +point.getVar());
                   System. out .println("y坐标" +point.getYar());
              
          }

}


结果:

x坐标20
y坐标北纬


3.指定多个泛型

class Point1<T,K>{//声明一个泛型类
          
      private  T  var; //声明一个泛型变量
     
      private K Yar;

      public T getVar() {
           return var ;
     }

      public void setVar(T var) {
           this .var = var;
     }

      public K getYar() {
           return Yar ;
     }

      public void setYar(K yar) {
           Yar = yar;
     }

      public Point1(T var, K yar) {
           this .var = var;
           Yar = yar;
     }

     
     
     
}


public class PointTest1 {
     
           public static void main(String[] args) {
              Point1<Integer,String> point= new Point1<Integer,String>(20,"北纬" );
               //point.setVar(20);
           //   Point1<String> point1=new Point1<String>();
           //   point.setYar("北纬");
                   System. out .println("x坐标" +point.getVar());
                   System. out .println("y坐标" +point.getYar());
              
          }

}

结果:
x坐标20
y坐标北纬

4.泛型的安全警告

class Point1<T,K>{//声明一个泛型类
          
      private  T  var; //声明一个泛型变量
     
      private K Yar;

      public T getVar() {
           return var ;
     }

      public void setVar(T var) {
           this .var = var;
     }

      public K getYar() {
           return Yar ;
     }

      public void setYar(K yar) {
           Yar = yar;
     }

      public Point1(T var, K yar) {
           this .var = var;
           Yar = yar;
     }

     
     
     
}


public class PointTest1 {
     
           public static void main(String[] args) {
               Point1 point= new Point1(20, "北纬" );//这里如果不指定泛型,那么系统就会擦除泛型,变为Object类型来接收

/**
警告消息:


Multiple markers at this line
     - Point1 is a raw type. References to generic type Point1<T,K> should be parameterized
     - Point1 is a raw type. References to generic type Point1<T,K> should be parameterized
     - Type safety: The constructor Point1(Object, Object) belongs to the raw type Point1. References to generic type Point1<T,K> 
     should be parameterized



*/
               //point.setVar(20);
           //   Point1<String> point1=new Point1<String>();
           //   point.setYar("北纬");
                   System. out .println("x坐标" +point.getVar());
                   System. out .println("y坐标" +point.getYar());
              
          }

}

结果:

x坐标20
y坐标北纬


5.通配符

class Info<T>{
      private T var;

      public T getVar() {
           return var ;
     }

      public void setVar(T var) {
           this .var = var;
     }
     
     
}


public class TypeTest {

     
      public static void main(String[] args) {
          Info<String>i= new Info<String>();
          i.setVar( "like" );
           fun(i); //这里出现错误,无法传递
     }
     
      public static void fun(Info<Object> temp){
          System. out .println("内容" +temp);
     }
}

这样肯定是不行的,如果把代码改为这样:

class Info<T>{
      private T var;

      public T getVar() {
           return var ;
     }

      public void setVar(T var) {
           this .var = var;
     }
     
     
}


public class TypeTest {

     
      public static void main(String[] args) {
          Info<String>i= new Info<String>();
          i.setVar( "like" );
           fun(i); //这里出现错误,无法传递
     }
     
      public static void fun(Info temp){
          System. out .println("内容" +temp.getVar());
     }
}

结果:
内容like

但是这样有出现安全警告,那到底怎样才好喃?那就是要用泛型的通配符了



定义:表示可以使用任意的泛型对象


代码:
public class TypeTest {

     
      public static void main(String[] args) {
          Info<String>i= new Info<String>();
          i.setVar( "like" );
           fun(i); //这里出现错误,无法传递
     }
     
      public static void fun(Info<?> temp){//这里使用了统配符
          System. out .println("内容" +temp.getVar());
     }
}

结果:
内容like

6.受限泛型

受限泛型是指在泛型的操作过程中,可以指定一个泛型对象的范围上限和范围下限

格式:

    上限:
          声明对象:  类名称<? extends 类>对象名称
          声明类:访问权限 类名称<泛型标识 extends 类>

     下限:
            声明对象:  类名称<? super类>对象名称
         



代码:
声明泛型对象
public class TypeTest {

     
      public static void main(String[] args) {
          Info<String>i= new Info<String>();
          i.setVar( "like" );
           fun(i); //这里出现错误,无法传递
     }
     
      public static void fun(Info<? extends Number > temp){
          System. out .println("内容" +temp.getVar());
     }
}

上面出现错误,是因为,泛型只能接收数字类型

改下代码:
class Info<T>{
      private T var;

      public T getVar() {
           return var ;
     }

      public void setVar(T var) {
           this .var = var;
     }
     
     
}


public class TypeTest {

     
      public static void main(String[] args) {
          Info< Integer>i= new Info< Integer>();
          i.setVar(20);
           fun(i);
     }
     
      public static void fun(Info<? extends Number> temp){
          System. out .println("内容" +temp.getVar());
     }
}
结果:
内容20

也可以接收其他类型的数字

看代码:
//接收Double
public class TypeTest {

     
      public static void main(String[] args) {
          Info<Double>i= new Info<Double>();
          i.setVar(20.28);
           fun(i); //这里出现错误,无法传递
     }
     
      public static void fun(Info<? extends Number> temp){
          System. out .println("内容" +temp.getVar());
     }
}

结果:
内容20.28

其他的数字类型就不一一例举了


声明受限泛型类:

代码:

class Info<T extends Number>{//这里声明了受限泛型类
      private T var;

      public T getVar() {
           return var ;
     }

      public void setVar(T var) {
           this .var = var;
     }
     
     
}


public class TypeTest {

     
      public static void main(String[] args) {
          Info<Double>i= new Info<Double>();
          i.setVar(20.28);
           fun(i);
     }
     
      public static void fun(Info<? extends Number> temp){//这里声明受限泛型方法
          System. out .println("内容" +temp.getVar());
     }
}

结果:
内容20.28


泛型下限:

声明受限泛型下限对象:

public class TypeTest {

     
      public static void main(String[] args) {
          Info<Double>i= new Info<Double>();
          i.setVar(20.28);
           fun(i);
     }
     
      public static void fun(Info<? super Double> temp){//这里声明泛型下限对象
这里就说明最低接收Double,还可以接收比Double 更高的 Number,Object
          System. out .println("内容" +temp.getVar());
     }
}
结果:
内容20.28






代码:
class Info<T  extends Double >{//这里声明泛型上限
      private T var;

      public T getVar() {
           return var ;
     }

      public void setVar(T var) {
           this .var = var;
     }
     
     
}


public class TypeTest {

     
      public static void main(String[] args) {
          Info<Double>i= new Info<Double>();
          i.setVar(20.28);
           fun(i); //这里出现错误,无法传递
     }
     
      public static void fun(Info<? super Double> temp){
          System. out .println("内容" +temp.getVar());
     }
}
结果:
内容20.28
这段代码就是说明 怎样声明上限和下限一起使用

7.泛型与子类继承的限制

一个类的子类可以通过对象多态性来实例化父类对象,但是在泛型中子类无法为为父类实例化对象


代码:

public class TypeTest {

     
      public static void main(String[] args) {
          Info<Double>i= new Info<Double>();
          Info<Object>j= new Info<Object>();
          j= i; //这里会报错
          i.setVar(20.28);
          
          
          
     }
     
      public static void fun(Info<? super Double> temp){
          System. out .println("内容" +temp.getVar());
     }
}
子类不能实例化父类


8.泛型接口

泛型接口和普通接口也差不多,下面看代码就明白了

     
     interface Info<T>{
     
      public T getVar();
     
}


实现泛型接口有两种方式

          interface Info<T>{
     
      public T getVar();
     
}


public class TypeTest<T> implements Info<T>{
      private T var;

      public T getVar() {
           return var ;
     }

      public void setVar(T var) {
           this .var = var;
     }

      public static void main(String[] args) {
              TypeTest<String> test= new TypeTest<String>();
              test.setVar( "like" );
              System. out .println(test.getVar());
     }
     
}

结果:
like


还有一种

interface Info<T>{
     
      public T getVar();
     
}


public class TypeTest implements Info<String>{
      private String var;

      public String getVar() {
           return var ;
     }

      public void setVar(String var) {
           this .var = var;
     }

      public static void main(String[] args) {
            TypeTest test= new TypeTest();
            test.setVar( "like" );
           
            System. out .println(test.getVar());
     }
     
}

结果:
like

9.泛型数组
          
          public class TypeTest {
     
           public static void main(String[] args) {
               //Integer i[]={1,2,3,4,5};//静态初始化数组
              Integer i[]= fun1(1,2,3,4,5);
               fun2(i);
          }
     
           public static <T> T[] fun1(T...arg){ //可变参数和泛型数组
               return arg;
          }
          
           public static <T> void fun2(T param[]){
               for (T t: param){
                   System. out .print(t+"," );
              }
          }

}

结果:
1,2,3,4,5,


数组就写到这里了,如果有不对的地方,请原谅