廖雪峰Java4反射与泛型-3范型-6super通配符
1.super通配符
1.1super通配符第一种用法
泛型的继承关系
Pair<Integer>不是Pair<Number>的子类,如
static void set(Pair<Integer> p, Integer first, Integer last){...}
set()不接受Pair<Number>
使用<? super Integer>使方法接收所有泛型类型为Integer或Integer超类的Pair类
package com.testArray;
public class PairHepler {
static void set(Pair<? super Integer> p,Integer first,Integer last){
/**
* 对Pair<? super Integer> 调用setFirst()方法:
* 方法签名:void setFirst(? super Integer)
* 可以安全传入Integer类型的变量:p.setFirst(new Integer(123))
*/
p.setFirst(first);
p.setLast(last);
}
static Integer add(Pair<? extends Number> p){
/**
* 对Pair<? super Integer>调用getFirst()方法:
* 方法签名:? super Integer getFirst()
* 无法赋值给Integer类型的变量。因为无法确定返回值就是Integer类型,可以确认其是Integer的超类,但无法确认就是Integer
*/
Number first = p.getFirst();
Number last = p.getLast();
return first.intValue()+last.intValue();
}
}
<? super Integer>的通配符:
* 允许调用set方法传入Integer的引用
* 不允许调用get方法获得Integer的引用
* 唯一例外:可以获取Object引用:Object o = p.getFirst();
void process(List<? super Integer> list){...}
class List<T>{
T.get(int index);//process方法不能调用
void add(T t);//process方法可以调用
void remove(T t);//process方法可以调用
}
1.2super通配符的第二种用法
<T super Integer>的通配符:
限定定义Pair<T>时只能是Integer或Integer的超类
public class Pair<T super Integer>{...}
Pair<Integer> ip = new Pair<>(1, 2);
Pair<Number> np = new Pair<>(1, 2);
Pair<String> sp = new Pair<>("a", "b");//error
2.extends和super的区别
方法参数为<? extends T>和方法参数为<? super T>的区别:
* <? extends T>允许调用方法获取T的引用
* <? super T>允许调用方法传入T的引用
public class Collections{
//把src的每个元素复制到dest中:List<? super T> dest目标,List<? extends T> src源文件
public static <T> void copy(List<? super T> dest, List<? extends T> src){
for(int i=0; i<src.size(); i++){
T t = src.get(i);
dest.add(t);
}
}
}
3.无限定通配符
public class Pair<T> {...}
public class PairHelper{
static boolean isNull(Pair<?> p){
return p.getFirst() == null || p.getLast() == null;
}
}
<?>的通配符:
?号即包括了extends的限制,页包括了super的限制
不允许调用set方法,null除外
只能调用get方法获取Object的引用
因此使用Pair<?>只能获取Object的引用,以及是否为null
Pair<?>和 Pair不同,通常情况下可以引入泛型参数<T>消除<?>通配符
Pair.java
package com.testArray;
public class Pair<T> {
private T first;
private T last;
public Pair(T first,T last){
this.first = first;
this.last = last;
}
public void setFirst(T first){
this.first = first;
}
public T getFirst() {
return first;
}
public void setLast(T last){
this.last = last;
}
public T getLast(){
return last;
}
public String toString(){
return "Pair(" + first+", "+last+")";
}
}
Main.java
package com.testArray;
public class Main {
public static void main(String[] args){
Pair<Integer> p = new Pair<>(0, 0);
System.out.println(p);
set(p, 123, 456);
System.out.println(p);
Pair<Number> n = new Pair<>(1.2,3.4);
System.out.println(n);
set(n,99,88);
System.out.println(n);
}
static void set(Pair<? super Integer> p, Integer first,Integer last){
p.setFirst(first);
p.setLast(last);
//Integer f = p.getFirst();
}
}

4.总结:
使用类似<? super Integer>通配符作为方法参数时表示:
* 方法内部可以调用传入Integer引用的方法:obj.setXXX(Integer n)
* 方法内部无法调用获取Integer引用的方法(Object除外)Integer n = obj.getXxx()
使用类似<T super Integer>定义泛型类时表示:
* 泛型类型限定为Integer或Integer的超类
无限定通配符<?>很少使用,可以用<T>替换
廖雪峰Java4反射与泛型-3范型-6super通配符的更多相关文章
- 廖雪峰Java4反射与泛型-3范型-5extends通配符
1.泛型的继承关系: Pair<Integer>不是Pair<Number>的子类 add()不接受Pair<Integer> Pair.java package ...
- 廖雪峰Java4反射与泛型-3范型-4擦拭法
1.擦拭法是Java泛型的实现方式. 编译器把类型视为Object. * 泛型代码编译的时候,编译器实际上把所有的泛型类型T统一视为Object类型.换句话说,虚拟机对泛型一无所知,所有的工作都是编译 ...
- 廖雪峰Java4反射与泛型-3范型-3编写泛型
编写泛型类比普通的类要麻烦,而且很少编写泛型类. 1.编写一个泛型类: 按照某种类型(例如String)编写类 标记所有的特定类型例如String 把特定类型替换为T,并申明 Pair.java pa ...
- 廖雪峰Java4反射与泛型-3泛型-7泛型和反射
1.部分反射API是泛型 1.1获取反射API的泛型 部分反射API是泛型,如Class<T>是泛型 //如果使用Class,不带泛型,出现compile warning编译警告 Clas ...
- 廖雪峰Java4反射与泛型-2注解-3处理注解
1.处理注解 注解本身对对代码逻辑没有任何影响 SOURCE类型的注解在编译期就被丢掉了 CLASS类型的注解仅保存在class文件中 RUNTIME类型的注解在运行期可以被读取 如何使用注解由工具决 ...
- 廖雪峰Java4反射与泛型-1反射-2访问字段Field和3调用方法Method
2.字段Field 2.1.通过Class实例获取字段field信息: getField(name): 获取某个public的field,包括父类 getDeclaredField(name): 获取 ...
- 廖雪峰Java4反射与泛型-1反射-1Class类
1.Class类与反射定义 Class类本身是一种数据类型(Type),class/interface的数据类型是Class,JVM为每个加载的class创建了唯一的Class实例. Class实例包 ...
- 廖雪峰Java4反射与泛型-2注解-2定义注解
1.定义注解 使用@interface定义注解Annotation 注解的参数类似无参数方法 可以设定一个默认值(推荐) 把最常用的参数命名为value(推荐) 2.元注解 2.1Target使用方式 ...
- 廖雪峰Java4反射与泛型-2注解-1使用注解
1.Annotation定义 注解是放在Java源码的类.方法.字段.参数前的一种标签.如下 package com.reflection; import org.apache.logging.log ...
随机推荐
- C++数组排序
#include<stdio.h> #include<stdlib.h> #include<windows.h> #define SIZE 5 //数组中元素的数量 ...
- ISCC的 Web——WP
比赛已经结束了,自己做出来的题也不是很多,跟大家分享一下 第一题:比较数字大小 打开连接 在里面随意输入一个值,他会提示数字太小了 那么我们输入他允许的最大值试试 他还是提示太小了 我们知道做web‘ ...
- [Codeforces Round #492 (Div. 1) ][B. Suit and Tie]
http://codeforces.com/problemset/problem/995/B 题目大意:给一个长度为2*n的序列,分别有2个1,2,3,...n,相邻的位置可以进行交换,求使所有相同的 ...
- org.apache.commons.lang3.StringUtils中的StringUtils常用方法
https://my.oschina.net/funmo/blog/615202?p=1 public static void TestStr(){ //null 和 ""操作~~ ...
- Thinkphp,Jquery,Ajax异步发布
1.在提交表单的HTML页面的<head>中定义一个变量供Jquery使用 <script type='text/javascript'>var handleUrl='< ...
- JS 数组常用的方法
数组常用的方法: x.toString()方法:任何对象都有toString方法. 将任何对象转为字符串. 一般不主动调用,系统在需要时自动调用 x.valueOf()方法:同toStr ...
- linux配置防火墙
centos6.5 防火墙开放80端口 iptables -I INPUT -p tcp –dport 80 -j ACCEPT //注意,dport前面是两个-,其中-I是指在防火墙INPUT表最前 ...
- 数据库连接池——Druid
使用步骤: 1.导包,durid1.0.9 jar包 2.定义配置文件,properties文件,名字任意位置也任意, 3.加载文件 4.获得数据库连接池对象 通过DuridDataSourceFa ...
- AssemblyVersion和AssemblyFileVersion的区别
简而言之,AssemblyVersion: 是程序集的版本,.NET的CLR用,用于标识出该dll的版本信息,用于定义强名称的版本号: AssemblyFileVersion: 为编译器生成的文件加入 ...
- day10 内容大纲
01 去年内容回顾 01 去年内容回顾 *args **kwargs: 万能参数,动态参数 * 魔性用法: 函数的定义时,* ** 聚合. 函数的执行时,* ** 打散. 形参顺序: 位置参数,*ar ...