关闭

Java学习提要——认识'泛型'与其常见操作

标签: java泛型通配符extend泛型接口
156人阅读 评论(0) 收藏 举报
分类:

1.泛型技术

平时写代码,代码的类型如果不能确定,那会怎么办呢?
先看个错误的例子:

class Point {
    private Object x ;
    private Object y ;
    //set、get构造方法略
}
public class Nice {
    public static void main(String args[]) {
        //设置数据
        Point p = new Point() ;
        p.setX("字符串");
        p.setY(20);//运行之后才会报错
        //取出数据
        String x = (String) p.getX();
        String y = (String) p.getY();
        System.out.println( x + y );
    }
}

设置的时候存放的是int,那么取出时是String,两个没有任何关系的对象之间要发生强制转换,就会产生ClassCastException

重点!向上转型的核心目的在于统一操作的参数上,而向下转型的目的是操作子类定义的特殊功能
JDK1.5之后加入了泛型技术,其核心意义在于:类的定义的时候,可以使用一个标记,此标记可以表示类中属性或方法参数的类型标记,在使用的时候才动态的设置类型

泛型例:

class Point <T> {
    private T x ;
    private T y ;
    public void setX(T x){  //定义Type = T ,是一个类型
        this.x = x ;    //属性的类型不知道,由Point使用时动态决定
    }
    public void setY(T y){
        this.y = y ;
    }
    public T getX() {
        return x;
    }
    public T getY() {
        return y;
    }
}
public class Nice {
    public static void main(String args[]) {
        Point<String> p = new Point<String>() ;
        p.setX("中文");
        p.setY(10);//运行前报错
        //由于接受的类型就是String,所以不需要向下强制转型了,下面括号中可省略
        String x = p.getX();
        String y = p.getY();
        System.out.println(x + y);

    }
}

使用泛型可以避免向下转型的问题,从而解决类转换的安全隐患
泛型能够采用的类型只能是,即,不可以是基本类型,只能是引用类型
如:Point < Integer > p = new Point< Integer > ( );
注意:

1.如果没有设置具体的泛型类型,会有警告,且使用Object表示
2. JDK1.7之后实例化泛型可以省略,Point p = new Point< > ( );

2.通配符

内部类,先看看:

//假设下面所用到的类与方法都已成功添加
public class Nice {
    public static void main(String args[]) {
        Message<Integer> m = new Message<Integer>();
        m.setMsg(100);
        fun(m);//引用传递
    }
    public static void fun(Message temp) {
        temp.setMsg("hello") //输出hello
        System.out.println(temp.getMsg());
    }
}
//这种方法可以执行,但是它是带有警告的
//这个方法可以接受一个类的任意泛型,但是不可以修改,只能够取出,那么可以使用“?”来描述,只需将参数那里修改
public static void fun(Message<?> temp){...}

那么“?”通配符基础上还会有两个子的通配符:
  1. ? extends 类:设置泛型上限,可以在声明上和方法参数上
    如:? extends Number:意味着可以设置Number或者Number的子类(Integer,Double …)
  2. ? super 类:设置泛型下限,可以声明在方法参数上
    如:? super String : 意味着只能够设置String或者它的父类
下面看下两者的完整例子:

//设置泛型的上限
class Message <T extends Number> {
    private T msg ;
    public void setMsg(T msg) {
        this.msg = msg ;
    }
    public T getMsg() {
        return msg ;
    }
}
public class Nice {
    public static void main(String args[]) {
        Message<Integer> m = new Message<Integer>();
        m.setMsg(100) ;
        fun(m);
    }
    public static void fun(Message< ? extends Number> temp) {
        System.out.println(temp.getMsg());
    }
}
//当然了,非Number或者非Number的子类的话,那么就语法错误了
//设置泛型的下限
class Message <T> {   //下限就不是在这里加了
    private T msg ;
    public void setMsg(T msg) {
        this.msg = msg ;
    }
    public T getMsg() {
        return msg ;
    }
}
public class Nice {
    public static void main(String args[]) {
        Message<String> m = new Message<String>();
        m.setMsg(100) ;
        fun(m);
    }
    public static void fun(Message< ? super String> temp) {
        System.out.println(temp.getMsg());
    }
}

3.泛型接口

泛型类型不仅仅定义在一个类里,泛型也可以在接口上声明,称之为泛型接口
有两种形式:

// 1.子类继续设置泛型
interface IMessage<T> { //设置多个泛型接口,用逗号隔开
    public void print(T t) ;
}
class MessageImpl<T> implements IMessage<T> {
//子类也继续使用泛型,并且父类接口使用和子类的同样的泛型标记
    public void print(T t) {
        System.out.println(t);
    }
}
public class Nice {
    public static void main(String args [] ) {
        IMessage<String> msg = new MessageImpl<String>() ;
        msg.print("hello");
    }
}
//2.在子类不设置泛型,而为父接口明确定义一个泛型类型
interface IMessage<T> { //设置多个泛型接口,用逗号隔开
    public void print(T t) ;
}
class MessageImpl implements IMessage<String> { 
    public void print(String t) {
        System.out.println(t);
    }
}
public class Nice {
    public static void main(String args [] ) {
        IMessage<String> msg = new MessageImpl() ;//String可省
        msg.print("hello");
    }
}

4.泛型方法

泛型方法不一定非要在定义在支持泛型的类里
泛型方法例:

public class Nice {
    public static void main(String args[] ) {
        String str = fun("hello");
        System.out.println(str.length());
    }
    //T的类型由传入的参数类型决定
    public static <T> T fun(T t) {
        return t ;
    }   
}

5.总结

1.泛型解决的向下转型所带来的安全隐患,其核心的组成就是在声明类或接口的时候不设置参数或属性的类型
2.”?”可以接收任意的泛型类型,只能够取出,但是不能够修改

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场