No4.泛型

标题:通配符

package conll;

class Message<T>{
	private T msg;

	public T getMsg() {
		return msg;
	}

	public void setMsg(T msg) {
		this.msg = msg;
	}
	
}

public class TestDemo {

	public static void main(String[] args)  {
		 Message<String> m = new Message<String>();
		 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<Integer> m = new Message<Integer>();
		 m.setMsg(100);
		 fun(m);   //引用传递
	}
	public static void fun(Message<String> temp){
		System.out.println(temp.getMsg());
	}
}

代码1

public static void fun(Message<String> temp){
        System.out.println(temp.getMsg());
    }

代码2

public static void main(String[] args)  {
         Message<Integer> m = new Message<Integer>();
         m.setMsg(100);
         fun(m);   //引用传递
    }

代码1和代码2在标注颜色的地方不统一。

fun()方法里面接受的“Message<String>”那么就不能够使用了,并且fun()方法不能够针对于不同的泛类进行重载,因为方法地方重载认的只是参数的类型与泛型无关。

解决方法一:不设置参数方法的泛型

package conll;

class Message<T>{
	private T msg;

	public T getMsg() {
		return msg;
	}

	public void setMsg(T msg) {
		this.msg = msg;
	}
	
}

public class TestDemo {

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

问题:

public static void fun(Message temp){
        System.out.println(temp.getMsg());
    }

Message会出现警告信息,因为不设置泛型就会出现警告信息。这里再fun里面设置了String类型的数据,但是泛型本身设置的Integer方法。

package conll;

class Message<T>{
	private T msg;

	public T getMsg() {
		return msg;
	}

	public void setMsg(T msg) {
		this.msg = msg;
	}
	
}

public class TestDemo {

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

   所以现在需要解决的是,需要又一种方式可以接受一个类的任意的泛型类型,但是不能够修改只能取出,那么就可以使用?来描述。

package conll;

class Message<T>{
	private T msg;

	public T getMsg() {
		return msg;
	}

	public void setMsg(T msg) {
		this.msg = msg;
	}
	
}

public class TestDemo {

	public static void main(String[] args)  {
		 Message<Integer> m1 = new Message<Integer>();	
		 m1.setMsg(100);
		 fun(m1);   //引用传递
		
	}
	public  static void fun(Message<?> temp){ //不能够设置但是能够取出。
		
		System.out.println(temp.getMsg());
	}
}

 在“?”通配符里面基础上还会有两个子通配符。

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

           -?extends Number:意味着可以设置Number或则是Number的子类(Integer、Double....)

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

             -? super String :意味着只能够设置String或则它的父类Object

范例:

package conll;

class Message<T extends Number>{
	private T msg;

	public T getMsg() {
		return msg;
	}

	public void setMsg(T msg) {
		this.msg = msg;
	}
	
}

public class TestDemo {

	public static void main(String[] args)  {
		 Message<Integer> m1 = new Message<Integer>();	
		 m1.setMsg(100);
		 fun(m1);   //引用传递
		
	}
	public  static void fun(Message<? extends Number> temp){ //不能够设置但是能够取出。
		
		System.out.println(temp.getMsg());
	}
}

        如果设置了非Number或则子类的化,那么将出现语法错误。

范例:设置下限

package conll;

class Message<T >{
	private T msg;

	public T getMsg() {
		return msg;
	}

	public void setMsg(T msg) {
		this.msg = msg;
	}
	
}

public class TestDemo {

	public static void main(String[] args)  {
		 Message<String> m1 = new Message<String>();	
		 m1.setMsg("hello world");
		 fun(m1);   //引用传递
		
	}
	public  static void fun(Message<? super String> temp){ //不能够设置但是能够取出。
		
		System.out.println(temp.getMsg());
	}
}

看懂就好。

标题:泛型接口

     泛型不仅可以定义在一个类里面,那么泛型也可以在接口上声明,称为泛型接口。

范例:定义泛型接口


//如果是接口在前面加上字母I,例如:IMessage
//如果是抽象类就在前面加上Abstract,例如:AbstractMessage
//如果是普通类直接缩写,例如:Message
interface IMessage<T>{  //设置泛型接口
	public void print(T t);
}

在接口上必须要定义相应的子类,所以来讲如果要定义子类有两种形式。

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

package conll;

//如果是接口在前面加上字母I,例如:IMessage
//如果是抽象类就在前面加上Abstract,例如:AbstractMessage
//如果是普通类直接缩写,例如:Message
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 TestDemo {

	public static void main(String[] args)  {
		 IMessage<String> msg = new MessageImpl();
		 msg.print("hello world!");
		
	}
}

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

package conll;

//如果是接口在前面加上字母I,例如:IMessage
//如果是抽象类就在前面加上Abstract,例如:AbstractMessage
//如果是普通类直接缩写,例如:Message
interface IMessage<T>{  //设置泛型接口
	public void print(T t);
}
//子类也继续使用泛类,并且父接口使用和子类同样的泛型标记
class MessageImpl implements IMessage<String>{
	public void print(String t){
		System.out.println(t);
	}
}
public class TestDemo {

	public static void main(String[] args)  {
		 IMessage<String> msg = new MessageImpl();
		 msg.print("hello world!");
		
	}
}

标记:泛型方法

      泛型方法不一定非要定义在支持泛型的类里面。在之前所编写的所有存在有泛型的方法都是在泛型支持类里面定义。

范例:泛型方法

package conll;


public class TestDemo {

	public static void main(String[] args)  {
	    String str = fun("hello");
	    System.out.println(str.length());
	}
	public static <T> T fun(T t){
		return t;
	}
}

 能看懂泛型方法的标记就可以了。

总结:1.泛型解决的是向下转型所带来的安全隐患,其核心的组成就是在声明类或接口的时候不设置参数或属性的类型。

           2.“?”可以接收任意的泛型类型,只能够取出,但是不能修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值