【原】泛型-Java
泛型是Java SE5.0中新增的新特性,通过泛型使得在代码编译的时候就能检查类型安全,并且所有的强制类型转换都是自动和隐式的,从而提高代码的重用率。
Note:在JavaSE7+以后的版本中,构造函数可以省略泛型类型。省略的类型可以从变量的类型推断得出。如:List<Map<String,String>> listmaps=new ArrayList<>();
- 泛型类型的继承规则
- 通配符类型
- 通配符的超类型限定
- 无限定通配符
- 泛型反射
1.泛型类型的继承规则
无论S与T有什么联系,通常,Pair<S> 与Pair<T>没有什么联系
如下所示:public class Manager extends Employee
可见,泛型中<>前面的类的继承关系才会起作用,而<>内部的类的继承关系就不起作用

2.通配符类型
Pair<? extends Employee>
利用通配符可以解决上述中出现的<>内不能继承的问题
3.通配符的超类型限定
? super Manager,这个通配符限制为Manager的所有超类型
4.无限定通配符
Pair<?> p
对于2.3.4让我们通过代码来详细了解一下吧。
public class PairTest3
{
public static void main(String[] args)
{
Manager ceo = new Manager("Gus Greedy", 800000, 2003, 12, 15);
Manager cfo = new Manager("Sid Sneaky", 600000, 2003, 12, 15);
Pair<Manager> buddies = new Pair<>(ceo, cfo);
printBuddies(buddies); ceo.setBonus(1000000);
cfo.setBonus(500000);
Manager[] managers = { ceo, cfo }; Pair<Employee> result = new Pair<>();
minmaxBonus(managers, result);
System.out.println("first: " + result.getFirst().getName()
+ ", second: " + result.getSecond().getName());
maxminBonus(managers, result);
System.out.println("first: " + result.getFirst().getName()
+ ", second: " + result.getSecond().getName()); } public static void printBuddies(Pair<? extends Employee> p)
{
Employee first = p.getFirst();
Employee second = p.getSecond();
System.out.println(first.getName() + " and " + second.getName() + " are buddies.");
} //超类型通配符
public static void minmaxBonus(Manager[] a, Pair<? super Manager> result)
{
if (a == null || a.length == 0) return;
Manager min = a[0];
Manager max = a[0];
for (int i = 1; i < a.length; i++)
{
if (min.getBonus() > a[i].getBonus()) min = a[i];
if (max.getBonus() < a[i].getBonus()) max = a[i];
}
result.setFirst(min);
result.setSecond(max);
} public static void maxminBonus(Manager[] a, Pair<? super Manager> result)
{
minmaxBonus(a, result);
PairAlg.swapHelper(result); // OK--swapHelper captures wildcard type
}
} class PairAlg
{
//无限定通配符
//该方法用来测试一个pair是否包含一个 引用
public static boolean hasNulls(Pair<?> p)
{
return p.getFirst() == null || p.getSecond() == null;
}
public static void swap(Pair<?> p) { swapHelper(p); } public static <T> void swapHelper(Pair<T> p)
{
T t = p.getFirst();
p.setFirst(p.getSecond());
p.setSecond(t);
}
}
5.泛型反射
public class GenericReflectionTest
{
public static void main(String[] args)
{
// read class name from command line args or user input
String name;
if (args.length > 0) name = args[0];
else
{
Scanner in = new Scanner(System.in);
System.out.println("Enter class name (e.g. java.util.Collections): ");
name = in.next();
} try
{
// print generic info for class and public methods
Class<?> cl = Class.forName(name);
printClass(cl);
for (Method m : cl.getDeclaredMethods())
printMethod(m);
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
} public static void printClass(Class<?> cl)
{
System.out.print(cl);
printTypes(cl.getTypeParameters(), "<", ", ", ">", true);
Type sc = cl.getGenericSuperclass();
if (sc != null)
{
System.out.print(" extends ");
printType(sc, false);
}
printTypes(cl.getGenericInterfaces(), " implements ", ", ", "", false);
System.out.println("----");
} public static void printMethod(Method m)
{
String name = m.getName();
System.out.print(Modifier.toString(m.getModifiers()));
System.out.print(" ");
printTypes(m.getTypeParameters(), "<", ", ", "> ", true);
//System.out.println(); printType(m.getGenericReturnType(), false);
System.out.print(" ");
System.out.print(name);
System.out.print("(");
printTypes(m.getGenericParameterTypes(), "", ", ", "", false);
System.out.println(")");
} public static void printTypes(Type[] types, String pre, String sep, String suf,
boolean isDefinition)
{
if (pre.equals(" extends ") && Arrays.equals(types, new Type[] { Object.class })) return;
if (types.length > 0) System.out.print(pre);
for (int i = 0; i < types.length; i++)
{
if (i > 0) System.out.print(sep);
printType(types[i], isDefinition);
}
if (types.length > 0) System.out.print(suf);
} public static void printType(Type type, boolean isDefinition)
{
if (type instanceof Class)
{
Class<?> t = (Class<?>) type;
System.out.print(t.getName());
}
else if (type instanceof TypeVariable)
{
TypeVariable<?> t = (TypeVariable<?>) type;
System.out.print(t.getName());
if (isDefinition)
printTypes(t.getBounds(), " extends ", " & ", "", false);
}
else if (type instanceof WildcardType)
{
WildcardType t = (WildcardType) type;
System.out.print("?");
printTypes(t.getUpperBounds(), " extends ", " & ", "", false);
printTypes(t.getLowerBounds(), " super ", " & ", "", false);
}
else if (type instanceof ParameterizedType)
{
ParameterizedType t = (ParameterizedType) type;
Type owner = t.getOwnerType();
if (owner != null)
{
printType(owner, false);
System.out.print(".");
}
printType(t.getRawType(), false);
printTypes(t.getActualTypeArguments(), "<", ", ", ">", false);
}
else if (type instanceof GenericArrayType)
{
GenericArrayType t = (GenericArrayType) type;
System.out.print("");
printType(t.getGenericComponentType(), isDefinition);
System.out.print("[]");
}
}
}
【原】泛型-Java的更多相关文章
- 原子类java.util.concurrent.atomic.*原理分析
原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...
- 点单登录原理和java实现简单的单点登录
引用自:http://blog.csdn.net/zuoluoboy/article/details/12851725 摘要: 单点登录(SSO)的技术被越来越广泛地应用到各个领域的软件系统当中.本文 ...
- Java 泛型 Java使用泛型的意义
Java 泛型 Java使用泛型的意义 @author ixenos 直接意义 在编译时保证类型安全 根本意义 a) 类型安全问题源自可复用性代码的设计,泛型保证了类型安全的复用模板 b) 使用复用性 ...
- Java 原子类 java.util.concurrent.atomic
Java 原子类 java.util.concurrent.atomic 1.i++为什么是非线程安全的 i++其实是分为3个步骤:获取i的值, 把i+1, 把i+1的结果赋给i 如果多线程执行i++ ...
- 【原】Java学习笔记027 - 泛型
package cn.temptation.test; import java.util.ArrayList; import java.util.Iterator; public class Samp ...
- C++泛型 && Java泛型实现机制
C++泛型 C++泛型跟虚函数的运行时多态机制不同,泛型支持的静态多态,当类型信息可得的时候,利用编译期多态能够获得最大的效率和灵活性.当具体的类型信息不可得,就必须诉诸运行期多态了,即虚函数支持的 ...
- 【原】Java学习笔记026 - 集合
package cn.temptation; public class Sample01 { public static void main(String[] args) { // 需求:从三国演义中 ...
- 【原】Java学习笔记023 - 字符串缓冲区_正则表达式
package cn.temptation; import java.util.Arrays; public class Sample01 { public static void main(Stri ...
- 【原】Java学习笔记022 - 字符串
package cn.temptation; public class Sample01 { public static void main(String[] args) { // 字符串 // 定义 ...
随机推荐
- MAC 上找不到.bash_profile或者ect/profile该怎么办?
开发Android的环境要重新在Mac上搭建,结果在配置环境变量时找不到.bash_profile文件.查过很多资料解决方案都很笼统,结果还是在英文网站上找到解决方法. 1. 启动终端Termin ...
- Python 出现需要使用fPIC重新编译的问题
在已经存在python安装环境的情况下,当安装第三方的包的时候出现报错提示 /usr/bin/ld: .../lib/libpython2.7.a(abstract.o): relocation R_ ...
- MVC-EditorFor与TextBoxFor的区别
EditorFor会根据后面提供的数据类型自动判断生成的控件类型(比如TextBox,CheckBox等): TextBoxFor生成的只是一个TextBox.
- python 内置函数 getattr
class Getattr_Test(): var_a = 'abc' def methodA(self): var_b = 'xyz' return var_b t = Getattr_Test() ...
- C++编写操作系统(1):基于 EFI 的 Bootloader
很久以前就对操作系统很好奇,用了这么多年Windows,对他的运作机理也不是很清楚,所以一直想自己动手写一个,研究一下操作系统究竟是怎么实现的.后来在网上也找到过一些教程(比如:<自己动手写操作 ...
- JavaSE replaceAll 方法
private String srcStr = "index\\.php\\?action=";//要替换的原字符串 private String destStr = " ...
- Spring 配置XML文件头部文件格式
普通格式: <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns:xsi="ht ...
- [杂题]URAL1822. Hugo II's War
看懂题意的请直接跳过下一坨! 本人有表达障碍! ========================================== 题意: (题意真的很难很难懂啊!!! 去他娘的**) 有一个王国 ...
- 获取C#中exe程序的实例名
获取sanjiao.frmsanjiao string strPass = @"D:\WinAutoTest\sanjiao.exe"; Assembly assebly = As ...
- 汉字与区位码互转(天天使用的String存储的是内码),几个常见汉字编码,附有读书笔记
汉=BABA(内码)=-A0A0=2626(区位码)字=D7D6(内码)=-A0A0=5554(区位码) 各种编码查询表:http://bm.kdd.cc/ “啊”字是GB2312之中的第一个汉字,会 ...