泛型-25

引入泛型
观察代码:
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;
}
}
范例:实现int整型数据
public class Listenf {
public static void main(String[] args) {
//第一层次:设置坐标数据
Point point=new Point();
point.setX(10);//向上转型为Object
point.setY(20);//向上转型为Object
//第二层次:取得坐标数据
int x=(Integer)point.getX();//向下转型
int y=(Integer)point.getY();//向下转型
System.out.println("x="+x+"y="+y);
}
}
范例:实现doublic型数据
public class Listenf {
public static void main(String[] args) {
//第一层次:设置坐标数据
Point point=new Point();
point.setX("东经100度");//向上转型为Object
point.setY("北纬20度");//向上转型为Object
//第二层次:取得坐标数据
String x=(String)point.getX();//向下转型
String y=(String)point.getY();//向下转型
System.out.println("x="+x+"y="+y);
}
}
Object保存的范围太大了,那么在程序会有隐患。
范例:观察问题
public class Listenf {
public static void main(String[] args) {
//第一层次:设置坐标数据
Point point=new Point();
point.setX(10);//向上转型为Object
point.setY("北纬20度");//向上转型为Object
//第二层次:取得坐标数据
String x=(String)point.getX();//向下转型
String y=(String)point.getY();//向下转型
System.out.println("x="+x+"y="+y);
}
}
此时程序编译没有错误,但是运行会发现“ClassCastException”,所以会有安全隐患。
事情上,所有对象的向下转型都有可能存在这种安全隐患。
泛型解决:
所谓泛型指的是类之中定义的属性,在程序编译的时候不给出具体的类型,只给出一个类型的占位标记,而后使用此类产生对象时,再设置具体类型
范例:利用泛型修改
package listen;
class Pointa<T>{
private T x;
private T y;
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public T getY() {
return y;
}
public void setY(T y) {
this.y = y;
}

}
public class Listenfa {
public static void main(String[] args) {
//第一层次:设置坐标数据
Pointa<String> point=new Pointa<String>();
point.setX("东经100度");
point.setY("北纬20度");
//第二层次:取得坐标数据
String x=point.getX();
String y=point.getY();
System.out.println("x="+x+"y="+y);
}
}
泛型的出现,取消了向下转型,而向下转型取消后就相当于消除所有了ClassCastException的安全隐患,需要注意的是,使用泛型类型的时候
只能是用使用引用类型,即;如果要保存的是int或是double,就用包装类操作
范例:保存int
package listen;
class Pointb<T>{
private T x;
private T y;
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public T getY() {
return y;
}
public void setY(T y) {
this.y = y;
}

}
public class Listenfb {
public static void main(String[] args) {
//第一层次:设置坐标数据
Pointb<Integer> point=new Pointb<Integer>();
point.setX(10);
point.setY(20);
//第二层次:取得坐标数据
int x=point.getX();
int y=point.getY();
System.out.println("x="+x+"y="+y);
}
}
如下代码,到今天还是有人用,这样代码并不好
public class Listenfb {
public static void main(String[] args) {
//第一层次:设置坐标数据
Pointb point=new Pointb();
point.setX(10);
point.setY(20);
//第二层次:取得坐标数据
int x=(Integer)point.getX();
int y=(Integer)point.getY();
System.out.println("x="+x+"y="+y);
}
}
通配符(次重点)
重新定义一个泛型类
class Info<T>{
private T msg;


public T getMsg() {
return msg;
}


public void setMsg(T msg) {
this.msg = msg;
}
}
下面要针对Info类的对象实现一次引用传递
public class Listeng {
public static void main(String[] args) {
// TODO Auto-generated method stub
Info<String> info=new Info<String>();
info.setMsg("hello world .");
fun(info);
}
public static void fun(Info<String> temp) {
System.out.println(temp.getMsg());
}
}
但是既然是设置泛型,肯定不可能只是String一种,有可能设置其它类型
范例:观察问题出现
public class Listeng {
public static void main(String[] args) {
// TODO Auto-generated method stub
Info<Integer> info=new Info<Integer>();
info.setMsg(100);
fun(info);
}
public static void fun(Info<String> temp) {
System.out.println(temp.getMsg());
}
}
此时,如果传递一个"Info<Integer>",那么fun()方法是不可能使用的。如果用重载也不可能,因为重载的看重的是数据类型。之前解决的参数
统一问题,现在又重新回来了。
范例:参数上不使用泛型
public class Listeng {
public static void main(String[] args) {
// TODO Auto-generated method stub
Info<String> info=new Info<String>();
info.setMsg("Hello World .");
fun(info);
}
public static void fun(Info temp) {//参数上不使用泛型
System.out.println(temp.getMsg());
}
}
如下不设置泛型,操作的数据形式就可能出现混乱。我们需要一个可以接收任意的泛型类型,但是又不修改里面数据,并且可以取得里面数据的操作
package listen;
class Info<T>{
private T msg;


public T getMsg() {
return msg;
}


public void setMsg(T msg) {
this.msg = msg;
}
}
public class Listeng {
public static void main(String[] args) {
// TODO Auto-generated method stub
Info<String> info=new Info<String>();
info.setMsg("可乐");
fun(info);
}
public static void fun(Info temp) {
temp.setMsg(100); //现在修改为Integer
System.out.println(temp.getMsg());
}
}
利用通配符来完成此功能
范例:使用“?”解决
public class Listenga {
public static void main(String[] args) {
// TODO Auto-generated method stub
Infoa<String> info=new Infoa<String>();
info.setMsg("可乐");
fun(info);
}
public static void fun(Infoa<?> temp) {
System.out.println(temp.getMsg());
}
}
单数“?”的基础上扩充两个子类的通配符
设置泛型上限:? extends类(T extends 类)
例如:“T extends Number”,表示此处只能设置Number和Number的子类(Integer)
设置泛型下限:? super 类:
例如:? super String,表示只能够设置String或者String的父类Object
范例:设置泛型上限:
package listen;
class Info<T>{
private T msg;


public T getMsg() {
return msg;
}


public void setMsg(T msg) {
this.msg = msg;
}
}
public class Listenga {
public static void main(String[] args) {
// TODO Auto-generated method stub
Infoa<Integer> info=new Infoa<Integer>();
info.setMsg(100);
fun(info);
}
public static void fun(Infoa<? extends Number> temp) {
System.out.println(temp.getMsg());
}
}
范例:设置泛型下限:
class Info<T>{
private T msg;


public T getMsg() {
return msg;
}


public void setMsg(T msg) {
this.msg = msg;
}
}
public class Listenga {
public static void main(String[] args) {
// TODO Auto-generated method stub
Infoa<String> info=new Infoa<String>();
info.setMsg("Hello World .");
fun(info);
}
public static void fun(Infoa<? super String> temp) {
System.out.println(temp.getMsg());
}
}


泛型接口:
在之前创建的泛型都是在类的定义上使用的,那么也可以在接口上使用泛型
范例:在接口上定义泛型
interface Message<T>{
public void print(T msg) ;
}
对于这样的接口有两种实现方式
方式一:在子类实现接口后继续使用泛型
package listen;
interface Message<T>{
public void print(T msg) ;
}
class MessageImp<T> implements Message<T>{
public void print(T msg) {
System.out.println(msg);
}
}
public class Listengb {
public static void main(String[] args) {
// TODO Auto-generated method stub
Message<String> message=new MessageImp<String>();
message.print("hello");
}
}
方式二:子类直接设置具体的泛型类型
package listen;
interface Message<T>{
public void print(T msg) ;
}
class MessageImp implements Message<String>{
public void print(T msg) {
System.out.println(msg);
}
}
public class Listengb {
public static void main(String[] args) {
// TODO Auto-generated method stub
Message<String> message=new MessageImp();
message.print("hello");
}
}
泛型方法
接触到泛型方法都是声明在泛型类之中,而现在所讲解的泛型方法指的是在没有泛型声明的类上定义的方法
范例:定义泛型方法
package listen;
public class Listenh {
public static void main(String[] args) {
// TODO Auto-generated method stub
Integer temp[]=fun(1,2,3);
for(Integer x : temp) {
System.out.println(x);
}
}
public static<T> T[] fun(T ... args) {//T是一个泛型标记,其类型由参数类型决定
return args;
}
}
知道这是泛型方法,知道泛型的类型由参数决定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值