码迷,mamicode.com
首页 > 编程语言 > 详细

Java 泛型

时间:2019-05-25 09:20:45      阅读:122      评论:0      收藏:0      [点我收藏+]

标签:代码   main   泛型类   mes   pre   参数   方法   基本数据类型   原因   

Java 泛型技术产生的原因:

package cn.mldn.utli;

class Point {
    private Object x ;
    private Object y ;
    public void setX( Object x ) {
        this.x = x ;
    }
    public void setY( Object y ) {
        this.y = y ;
    }
    public Object getX() {
        return x ;
    }
    public Object getY() {
        return y ;
    }
}

public class TestDemo {

    public static void main(String[] args) {
        Point p = new Point() ;
        p.setX(10);
        p.setY(20);
        
        int x = (Integer) p.getX();
        int y = (Integer) p.getY();
        System.out.println(x + y) ;
    }
}

 

 上述的程序中,利用Point类存储整型数据,利用Object对象进行存储,向下转型为int型

public class TestDemo {

    public static void main(String[] args) {
        Point p = new Point() ;
        p.setX(10.1);
        p.setY(20.2);
        
        double x = (Double) p.getX();
        double y = (Double) p.getY();
        System.out.println(x + y) ;
    }
}

 

 上述代码则是利用Point类存储小数,利用Object对象进行存储,向下转型为Double型

public class TestDemo {

    public static void main(String[] args) {
        Point p = new Point() ;
        p.setX("上海");
        p.setY("南京");
        
        String x = (String) p.getX();
        String y = (String) p.getY();
        System.out.println(x + y) ;
    }
}

 

  上述代码则是利用Point类存储String数据内容,利用Object对象进行存储,向下转型为String型

————————————————

上述的三段代码,均利用Point类进行三种不同类型的多类型同对象的存储,而Point类中是利用Object进行存储的,于是可以在调用处通过向下转型的方式将Object转为int/double/String等类型数据(装箱/拆箱)。

 

泛型技术:类在定义的时候可以只用一个标记,此标记表示类中属性或方法参数的类型标记,在使用的时候才动态的设置:

package cn.mldn.utli;
// 此时设置的T在Point定义上只表示一个标记,在使用的时候需要为其设置具体额类型
class Point<T> {  // Type = T , 是一个类型
    private T x ; // x的属性类型不明,有Point在使用时动态使用
    private T y ;
    public void setX( T x ) {
        this.x = x ;
    }
    public void setY( T y ) {
        this.y = y ;
    }
    public T getX() {
        return x ;
    }
    public T getY() {
        return y ;
    }
}

 

  在使用Point类的时候才取设置的内容,也就是设置了类中属性的类型;

public class TestDemo {

    public static void main(String[] args) {
        Point<String> p = new Point<String>() ;
     // 利用的就是包装类的自动装箱功能 p.setX(
"上海"); p.setY("南京"); // 由于泛型的特性,使用的时候动态的设置Point接收的类型为String类型,所以返回的也是String类型就不用在转型了 String x = p.getX(); String y = p.getY(); System.out.println(x + y) ; } }

 

  使用泛型之后,所有类中属性的类型都是动态设置的,而所有使用泛型标记的方法参数类型也都是会发生改变。由此避免了向下转型的安全问题隐患。

  如果是采用泛型,那么它能够接受的数据类型只能是基本数据类型的包装类表示,不可以引用类型!

 

#  在使用泛型类或者接口的时候,没有设置泛型的具体类型,会报错。(如果在没有设置泛型的具体类型的时候,所有泛型使用Object描述泛型的数据类型)

#  在JDK1.7后可以简化泛型:可以将实例化的泛型具体类型的定义省略

 

——————————

泛型通配符:

package cn.mldn.utli;

class Message<T> {  
    private T msg ;
    public void setMsg(T msg) {
        this.msg = msg ;
    }
    public T getMsg() {
        return msg ;
    }
}

public class TestDemo {

    public static void main(String[] args) {
        Message<String> m = new Message<> ();
        m.setMsg("Hello World!");
        fun(m) ;  // 引用传递
    }
    public static void fun(Message<String> temp) {
        System.out.println(temp.getMsg()) ;
    }
}

 

  上述代码为Message类设置的是一个String的泛型对象;

  如果我们需要一个可以接收任何类型的泛型数据,则可以使用 “?” 符号代替 "<>" 定义类型;如此以来则可以接收任何的泛型,但是不可以更改,只可以取出。

public class TestDemo {

    public static void main(String[] args) {
        Message<String> m = new Message<> ();
        m.setMsg("Hello World!");
        fun(m) ;  // 引用传递
    }
    public static void fun(Message<?> temp) {
        System.out.println(temp.getMsg()) ;
    }
}

 

  在 “?”的通配符上 还有两个子通配符:

    ~ ? extends 类:设置泛型上限,可以在泛型声明上和方法参数上使用;

        |-- ? extends  Number : 意味着可以设置Number或者子类的泛型

    ~ ? super 类: 设置泛型的下限,方法参数上使用;

        |-- ?super String : 意味只能设置String或者它的父类(Object)

 

泛型接口:

 定义泛型接口

interface Message<T> { //设置泛型接口
    public void print(T t) ;
}

 

在接口上定义其相应的子类,定义子类主要有两种形式:

形式一:在子类上继续设置泛型

package cn.mldn.utli;

interface Message<T> { //设置泛型接口
    public void print(T t) ;
}
class MessageImpl<T> implements Message<T> {
    public void print(T t) {
        System.out.println(t) ;
    }
}

public class TestDemo {

    public static void main(String[] args) {
        Message<String> msg = new MessageImpl<String>() ; // 向上转型实例化
        msg.print("Hello World!");
    }    
}

形式二:在子类不设置泛型,而父接口明确定义一个泛型类型

package cn.mldn.utli;

interface Message<T> { //设置泛型接口
    public void print(T t) ;
}
class MessageImpl implements Message<String> {
// 接口泛型的第二种定义方法,直接在实现接口的接口处明确一个泛型类型;由此实例化的时候不用设置泛型的具体类型
    public void print(String t) {
        System.out.println(t);        
    }
    
}

public class TestDemo {

    public static void main(String[] args) {
        Message msg = new MessageImpl() ; // 向上转型实例化
        msg.print("Hello World!");
    }    
}

 

-------------------------------

泛型方法:

  泛型方法不一定定义在支持泛型的类中。

泛型方法的定义:

package cn.mldn.utli;

public class TestDemo {

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

 

————————

泛型总结:

  泛型特性解决的是向下转型所带来的安全隐患,其核心的组成就是在声明类或接口中不用设置具体的参数类型;

  ? 符号可以接收任意的泛型类型,但是只能够取出,不能够修改

~~~~

Java 泛型

标签:代码   main   泛型类   mes   pre   参数   方法   基本数据类型   原因   

原文地址:https://www.cnblogs.com/wangyuyang1016/p/10907191.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!