原创:http://write.blog.csdn.net/mdeditor#!postId=51405639
泛型优点:
泛型是jsk1.5使用的新特性。
泛型最大的好处就是类型检查,尤其是对集合非常有用,泛型并且实现了重要的功能。
泛型的好处
1、将运行时的异常提前至了编译时
2、拒绝了无畏的类型转换。
/**
泛型在集合中的常见应用:
ArrayList<String> list = new ArrayList<String>(); true 推荐使用。
ArrayList<Object> list = new ArrayList<String>(); false
ArrayList<String> list = new ArrayList<Object>(); false
//以下两种写法主要是为了兼顾新老系统的兼用性问题。
*
ArrayList<String> list = new ArrayList(); true
ArrayList list = new ArrayList<String>(); true
注意: 泛型没有多态的概念,左右两边的数据 类型必须 要一致,或者只是写一边的泛型类型。
推荐使用: 两边都写泛型。
*/
public class Demo1 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>(); //<String> 表示该容器只能存储字符串类型 的数据。
list.add("aa");
list.add("bb");
list.add("cc");
for(int i = 0 ; i < list.size() ; i++){
String str = list.get(i);
System.out.println("大写:"+ str.toUpperCase());
}
MyUtil.print(list);
ArrayList<String> list2 = MyUtil.getList();
}
}
自定义泛型方法
/*
需求: 定义一个方法可以接收任意类型的参数,而且返回值类型必须 要与实参的类型一致。
自定义泛型: 自定义泛型就是一个数据类型的占位符或者是一个数据类型的变量。
方法上自定义泛型:
修饰符 <声明自定义的泛型>返回值类型 函数名(使用自定义泛型 ...){
}
在泛型中不能使用基本数据类型,如果需要使用基本数据类型,那么就使用基本数据类型对应的包装类型。
byte----> Byte
short---> Short
int-----> Integer
long----> Long
double ----> Double
float -----> Float
boolean-----> Boolean
char--------> Character
方法泛型注意的事项:
1. 在方法上自定义泛型,这个自定义泛型的具体数据类型是在调用该方法的时候传入实参时确定具体的数据类型的。
2. 自定义泛型只要符合标识符 的命名规则即可, 但是自定义泛型我们一般都习惯使用一个大写字母表示。 T E
*/
public class Demo2 {
public static void main(String[] args) {
String str = getData("abc");
Integer i = getData(123);
}
public static <abc>abc getData(abc o){
return o;
}
}
泛型类:
泛型类注意事项:
- 在类上自定义泛型的具体数据类型是在使用该类的时候创建对象的时候确定。
- 如果一个类在类上已经声明了自定义泛型,如果使用该类创建对象的时候没有指定泛型的具体数据类型,那么默认为Object类型。
- 在类上自定义泛型不能用于静态的方法,如果静态方法需要使用自定义泛型,那么要在方法上自己声明使用。
首先编写一个数组的工具类:
/**
此案例在MyArrarys类中,反复声明泛型<T>,能不能只声明一次,别的地方就能用。解决方法:泛型类
*/
class MyArrrays{
//元素翻转方法
public <T> void reverse(T[] arr){
for(int startIndex =0,endIndex=arr.length-1;startIndex<endIndex;startIndex++,endIndex--){
T temp = arr[startIndex];
arr[startIndex] = arr[endIndex];
arr[endIndex] = temp;
}
}
public <T>String toString(T[] arr){
StringBuilder sb = new StringBuilder();
for(int i = 0 ; i < arr.length ; i++){
if(i==0){
sb.append("["+arr[i]+",");
}else if(i==arr.length-1){
sb.append(arr[i]+"]");
}else{
sb.append(arr[i]+",");
}
}
return sb.toString();
}
}
public class Demo3 {
public static void main(String[] args) {
Integer[] arr = {10,12,14,19};
MyArrrays arrTool=new MyArrrays();
arrTool.reverse(arr);
System.out.println(arrTool.toString(arr));
}
}
泛型类的定义格式:
泛型类:
class 类名<声明自定义泛型>{
}
package dd;
class MyArrrays<T>{
//元素翻转
public void reverse(T[] arr){
for(int startIndex =0,endIndex=arr.length-1;startIndex<endIndex;startIndex++,endIndex--){
T temp = arr[startIndex];
arr[startIndex] = arr[endIndex];
arr[endIndex] = temp;
}
}
public String toString(T[] arr){
StringBuilder sb = new StringBuilder();
for(int i = 0 ; i < arr.length ; i++){
if(i==0){
sb.append("["+arr[i]+",");
}else if(i==arr.length-1){
sb.append(arr[i]+"]");
}else{
sb.append(arr[i]+",");
}
}
return sb.toString();
}
}
public class Demo3 {
public static void main(String[] args) {
Integer[] arr = {10,12,14,19};
MyArrrays arrTool=new MyArrrays();
arrTool.reverse(arr);
System.out.println(arrTool.toString(arr));
}
}
class MyArrays<T>{
//元素翻转
public void reverse(T[] arr){
for(int startIndex = 0, endIndex = arr.length-1 ; startIndex<endIndex ; startIndex++,endIndex--){
T temp = arr[startIndex];
arr[startIndex] = arr[endIndex];
arr[endIndex] = temp;
}
}
//
public String toString(T[] arr){
StringBuilder sb = new StringBuilder();
for(int i = 0 ; i < arr.length ; i++){
if(i==0){
sb.append("["+arr[i]+",");
}else if(i==arr.length-1){
sb.append(arr[i]+"]");
}else{
sb.append(arr[i]+",");
}
}
return sb.toString();
}
//在类上自定义的泛型这种方式不能用于静态的方法上,如果静态方法需要使用自定义泛型,那么要在方法上自己声明使用。
public static <T>void print(T[] t){
}
}
public class Demo3 {
public static void main(String[] args) {
Integer[] arr = {10,12,14,19};
//在类上自定义泛型的具体数据类型是在使用该类的时候创建对象的时候确定。
MyArrays<Integer> tool = new MyArrays<Integer>();
tool.reverse(arr);
System.out.println("数组的元素:"+tool.toString(arr));
MyArrays<String> tool2 = new MyArrays<String>();
String[] arr2 = {"aaa","bbb","ccc"};
tool2.reverse(arr2);
}
}
泛型接口:
泛型接口的定义格式:
interface 接口名<声明自定义泛型>{
}
泛型接口要注意的事项:
接口上自定义的泛型的具体数据类型是在实现一个接口的时候指定 的。
在接口上自定义的泛型如果在实现接口的时候没有指定具体的数据类型,那么默认为Object类型。
interface Dao<T>{
public void add(T t);
}
public class Demo4<T> implements Dao<T> {
public static void main(String[] args) {
Demo4<String> d = new Demo4<String>();
}
public void add(T t){
}
}
泛型的上下线
/*
泛型的上下限:
需求1: 定义一个函数可以接收接收任意类型的集合对象, 要求接收的集合对象只能存储Integer或者是Integer的父类类型数据。
需求2: 定义一个函数可以接收接收任意类型的集合对象, 要求接收的集合对象只能存储Number或者是Number的子类类型数据。
泛型中通配符: ?
? super Integer : 只能存储Integer或者是Integer父类元素。 泛型 的下限
? extends Number : 只能存储Number或者是Number类型的子类数据。 泛型上限
*/
public class Demo5 {
public static void main(String[] args) {
ArrayList<Integer> list1 = new ArrayList<Integer>();
ArrayList<Number> list2 = new ArrayList<Number>();
HashSet<String> set = new HashSet<String>();
//getData(set);
}
//泛型的上限
//定义一个函数可以接收接收任意类型的集合对象, 要求接收的集合对象只能存储Number或者是Number的子类类型数据。
public static void getData(Collection<? extends Number> c){
}
//泛型的下限
//定义一个函数可以接收接收任意类型的集合对象, 要求接收的集合对象只能存储Integer或者是Integer的父类类型数据。
public static void print(Collection<? super Integer> c){
}
}