泛型:
一種程序設計語言的新特性,於Java而言,在JDK 1.5開始引入。泛型就是在設計程序的時候定義一些可變部分,在具體使用的時候再給可變部分指定具體的類型。使用泛型比使用Object變量再進行強制類型轉換具備更好的安全性和可讀性。在Java中泛型主要體如今泛型類、泛型方法和泛型接口中。html
泛型類:
當一個類要操做的引用數據類型不肯定的時候,能夠給該類定義一個形參。用到這個類的時候,經過傳遞類型參數的形式,來肯定要操做的具體的對象類型。在JDK1.5以前,爲了提升代碼的通用性,一般把類型定義爲全部類的父類型:Object,這樣作有兩大弊端:1. 在具體操做的時候要進行強制類型轉換;2. 這樣仍是指定了類型,仍是不靈活,對具體類型的方法未知且不安全。java
泛型類的格式:在類名後面聲明類型變量<E> ,泛型類能夠有多個類型變量, 如:public class MyClass<K, V>
編程
何時使用泛型類?
只要類中操做的引用數據類型不肯定,就能夠定義泛型類。經過使用泛型類,能夠省去強制類型轉換和類型轉化異常的麻煩。安全
泛型類例子:
在這裏定義兩個類:Teacher 和 Student,定義一個泛型類Util<E>,其中getE()的做用是根據傳入的對象,返回具體的對象。在main()方法中,傳入具體的類型爲Student和Teacher,再進一步操做。
app
- public class Generic {
-
- public static void main(String[] args) {
- Util<Student> ts = new Util<Student>();
- System.out.println(ts.getE(new Student("Student","三年級" ,22)).getGrade());
- Util<Teacher> tt = new Util<Teacher>();
- System.out.println(tt.getE(new Teacher("Teacher",22)).getName());
-
- }
-
- }
- class Util<E>{
- public E getE(E e){
- return e;
- }
- }
-
- class Teacher{
- String name;
- int age;
- public Teacher() {
- }
-
- public Teacher(String name, int age){
- this.name = name;
- this.age = age;
- }
- Some Getter & Setter functions
- }
- class Student{
- String name;
- String grade;
- int number;
-
- public Student(String name, String grade, int number){
- this.name = name;
- this.grade = grade;
- this.number = number;
- }
- Some Getter & Setter functions
-
- }
public class Generic {
public static void main(String[] args) {
Util<Student> ts = new Util<Student>();
System.out.println(ts.getE(new Student("Student","三年級" ,22)).getGrade());
Util<Teacher> tt = new Util<Teacher>();
System.out.println(tt.getE(new Teacher("Teacher",22)).getName());
}
}
class Util<E>{
public E getE(E e){
return e;
}
}
class Teacher{
String name;
int age;
public Teacher() {
}
public Teacher(String name, int age){
this.name = name;
this.age = age;
}
Some Getter & Setter functions
}
class Student{
String name;
String grade;
int number;
public Student(String name, String grade, int number){
this.name = name;
this.grade = grade;
this.number = number;
}
Some Getter & Setter functions
}
泛型方法:
泛型方法也是爲了提升代碼的重用性和程序安全性。編程原則:儘可能設計泛型方法解決問題,若是設計泛型方法能夠取代泛型整個類,應該採用泛型方法。ide
泛型方法的格式:類型變量放在修飾符後面和返回類型前面, 如:public static <E> E getMax(T... in)oop
泛型方法例子:
- public class GenericFunc {
-
- public static void main(String[] args) {
- print("hahaha");
- print(200);
- }
-
- public static <T> void print(T t){
- System.out.println(t.toString());
- }
-
- }
public class GenericFunc {
public static void main(String[] args) {
print("hahaha");
print(200);
}
public static <T> void print(T t){
System.out.println(t.toString());
}
}
泛型接口:
將泛型原理用於接口實現中,就是泛型接口。post
泛型接口的格式:泛型接口格式相似於泛型類的格式,接口中的方法的格式相似於泛型方法的格式。
this
泛型接口例子:
MyInterface.javaspa
- public interface MyInteface<T> {
- public T read(T t);
- }
public interface MyInteface<T> {
public T read(T t);
}
Generic2.java
- public class Generic2 implements MyInterface<String>{
-
- public static void main(String[] args) {
- Generic2 g = new Generic2();
- System.out.println(g.read("hahaha"));
- }
-
- @Override
- public String read(String str) {
- return str;
- }
-
- }
public class Generic2 implements MyInterface<String>{
public static void main(String[] args) {
Generic2 g = new Generic2();
System.out.println(g.read("hahaha"));
}
@Override
public String read(String str) {
return str;
}
}
泛型通配符:
當操做的不一樣容器中的類型都不肯定的時候,並且使用的元素都是從Object類中繼承的方法,這時泛型就用通配符「?」來表示。
泛型的通配符:「?」 至關於 「? extends Object」
泛型通配符例子:
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.HashSet;
- import java.util.Iterator;
-
- public class AllCollectionIterator {
-
- public static void main(String[] args) {
- HashSet<String> s1 = new HashSet<String>();
- s1.add("sss1");
- s1.add("sss2");
- s1.add("sss3");
-
-
- ArrayList<Integer> a1 = new ArrayList<Integer>();
- a1.add(1);
- a1.add(2);
- a1.add(3);
- a1.add(4);
-
- printAllCollection(a1);
- System.out.println("-------------");
- printAllCollection(s1);
- }
-
- public static void printAllCollection(Collection<?> c){
- Iterator<?> iter = c.iterator();
- while (iter.hasNext()) {
- System.out.println(iter.next().toString());
-
- }
- }
-
- }
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
public class AllCollectionIterator {
public static void main(String[] args) {
HashSet<String> s1 = new HashSet<String>();
s1.add("sss1");
s1.add("sss2");
s1.add("sss3");
ArrayList<Integer> a1 = new ArrayList<Integer>();
a1.add(1);
a1.add(2);
a1.add(3);
a1.add(4);
printAllCollection(a1);
System.out.println("-------------");
printAllCollection(s1);
}
public static void printAllCollection(Collection<?> c){
Iterator<?> iter = c.iterator();
while (iter.hasNext()) {
System.out.println(iter.next().toString());
}
}
}
泛型限定:
泛型限定就是對操做的數據類型限定在一個範圍以內。限定分爲上限和下限。
上限:? extends E 接收E類型或E的子類型
下限:? super E 接收E類型或E的父類型
限定用法和泛型方法,泛型類用法同樣,在「<>」中表達便可。
一個類型變量或通配符能夠有多個限定,多個限定用「&」分隔開,且限定中最多有一個類,能夠有多個接口;若是有類限定,類限定必須放在限定列表的最前面。如:T extends MyClass1 & MyInterface1 & MyInterface2
在Collection<E>接口中addAll()就用到泛型限定。
addAll(Collection<? extends E> c)
將指定 collection 中的全部元素都添加到此 collection 中(可選操做)。
泛型限定的例子:
這個例子的做用是計算最大值。
- import java.util.Calendar;
- import java.util.GregorianCalendar;
-
- public class GenericGetMax {
-
- public static void main(String[] args) {
- String[] inArrStr = {"haha", "test", "nba", "basketball"};
- System.out.println(GetMax.findMax(inArrStr).toString());
- Integer[] inArrInt = {11, 33, 2, 100, 101};
- System.out.println(GetMax.findMax(inArrInt));
- GregorianCalendar[] inArrCal = {
- new GregorianCalendar(2016, Calendar.SEPTEMBER, 22),
- new GregorianCalendar(2016, Calendar.OCTOBER, 10)};
- System.out.println(GetMax.findMax(inArrCal).toZonedDateTime());
- }
- }
-
- class GetMax {
- @SafeVarargs
- public static <T extends Comparable> T findMax(T... in) {
- T max = in[0];
- for (T one : in) {
- if (one.compareTo(max) > 0) {
- max = one;
- }
- }
-
- return max;
- }
- }
import java.util.Calendar;
import java.util.GregorianCalendar;
public class GenericGetMax {
public static void main(String[] args) {
String[] inArrStr = {"haha", "test", "nba", "basketball"};
System.out.println(GetMax.findMax(inArrStr).toString());
Integer[] inArrInt = {11, 33, 2, 100, 101};
System.out.println(GetMax.findMax(inArrInt));
GregorianCalendar[] inArrCal = {
new GregorianCalendar(2016, Calendar.SEPTEMBER, 22),
new GregorianCalendar(2016, Calendar.OCTOBER, 10)};
System.out.println(GetMax.findMax(inArrCal).toZonedDateTime());
}
}
class GetMax {
@SafeVarargs
public static <T extends Comparable> T findMax(T... in) {
T max = in[0];
for (T one : in) {
if (one.compareTo(max) > 0) {
max = one;
}
}
return max;
}
}