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

原创 2016年08月31日 13:51:06

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.”?”可以接收任意的泛型类型,只能够取出,但是不能够修改

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Java学习提要——File类常见操作与目录操作

1.File类常见方法1)File类目录创建操作 问题引出: 在写File类操作的时候,是不可以直接输入一个不存在的目录,然后加入要创建的文件 这样系统会认为此时的路径是不可以使用的,...

Java学习提要——File类的基本操作

File类是一个与文件本身操作有关的类,但是不涉及到文件的具体内容File类的构造方法 设置完整路径:public File(String pathname); 设置父路径与子文件路径:pu...

Java学习提要——字符流与字节流的基本操作与区别

1.字符输出流:Writer//JDK1.1之后增加的,定义: public abstract class Write extends Object implements Appendable,Clo...

Java学习提要——IO操作的内存流

有一个应用需要进行IO操作,可是又不想产生文件。我们就可以使用内存来进行输入与输出的操作——使用内存流的场景 java.io包里提供两组操作: 字节内存流:ByteArrayI...

Java学习提要——输入流与输出流基本操作

能对文件进行内容操作的只有两种途径“字符流”和“字节流” 1.通过File类定义一个要操作的文件的路径; //如果操作不是文件,那么没有这一步 2.通过字节流或字符流的...

Java学习提要——异常的基本概念

异常是Java的一大特色,合理的使用异常处理,可以让程序更加健壮。1.异常的产生异常是导致程序中断执行的一种指令流,异常一旦出现并且没有进行合理的处理,那么程序就会中断执行。 产生异常: pub...

Java学习提要——基本网络编程Socket与echo

1.Socket通信 网络程序的开发,有着两个核心的类: 服务器类:ServerSocket,主要工作在服务器端,用于接收用户的请求; 客户端类:Socket,每一个...

Java学习提要——'Thread类'与'Runnable接口'基础

在Java之中,实现多线程有两种途径:   继承Thread类   实现Runnable接口(Callable接口)1.继承Thread类Thread类是一个支持多线程的功能类 格式: clas...

Java学习提要——System类基本

1.取得当前的系统时间:格式:public static long currentTimeMillis() 例://取得程序执行的时间 public class Nice { public...

Java学习提要——接口进阶

JDK1.8新特性1.接口定义增强应用场景:当有一个接口,比方其子类已经有一万个了,若是现在觉得扩充接口功能,而所有子类对于此方法的功能实现是完全一样的,要是以前我们要把每个子类都覆写上这个新方法。。...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)