Java 泛型-泛型类、泛型方法、泛型接口、通配符、上下限
2018-01-12 17:55
495 查看
泛型:
一种程序设计语言的新特性,于Java而言,在JDK 1.5开始引入。泛型就是在设计程序的时候定义一些可变部分,在具体使用的时候再给可变部分指定具体的类型。使用泛型比使用Object变量再进行强制类型转换具有更好的安全性和可读性。在Java中泛型主要体现在泛型类、泛型方法和泛型接口中。泛型类:
当一个类要操作的引用数据类型不确定的时候,可以给该类定义一个形参。用到这个类的时候,通过传递类型参数的形式,来确定要操作的具体的对象类型。在JDK1.5之前,为了提高代码的通用性,通常把类型定义为所有类的父类型:Object,这样做有两大弊端:1. 在具体操作的时候要进行强制类型转换;2. 这样还是指定了类型,还是不灵活,对具体类型的方法未知且不安全。泛型类的格式:在类名后面声明类型变量<E> ,泛型类可以有多个类型变量, 如:public class MyClass<K, V>
什么时候使用泛型类?
只要类中操作的引用数据类型不确定,就可以定义泛型类。通过使用泛型类,可以省去强制类型转换和类型转化异常的麻烦。泛型类例子:
在这里定义两个类:Teacher 和 Student,定义一个泛型类Util<E>,其中getE()的作用是根据传入的对象,返回具体的对象。在main()方法中,传入具体的类型为Student和Teacher,再进一步操作。[java] view plain copy print?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 }
泛型方法:
泛型方法也是为了提高代码的重用性和程序安全性。编程原则:尽量设计泛型方法解决问题,如果设计泛型方法可以取代泛型整个类,应该采用泛型方法。泛型方法的格式:类型变量放在修饰符后面和返回类型前面, 如:public static <E> E getMax(T... in)
泛型方法例子:
[java] view plain copy print?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()); }}
泛型接口:
将泛型原理用于接口实现中,就是泛型接口。泛型接口的格式:泛型接口格式类似于泛型类的格式,接口中的方法的格式类似于泛型方法的格式。
泛型接口例子:
MyInterface.java[java] view plain copy print?public interface MyInteface<T> {
public T read(T t);
}
public interface MyInteface<T> { public T read(T t);}
Generic2.java
[java] view plain copy print?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”
泛型通配符例子:
[java] view plain copy print?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 中(可选操作)。
泛型限定的例子:
这个例子的作用是计算最大值。[java] view plain copy print?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; }}
相关文章推荐
- Java 泛型-泛型类、泛型方法、泛型接口、通配符、上下限
- 牛客网Java刷题知识点之泛型概念的提出、什么是泛型、泛型在集合中的应用、泛型类、泛型方法、泛型接口、泛型限定上限、泛型限定下限、 什么时候使用上限?泛型限定通配符的体现
- Java 泛型-泛型类、泛型方法、泛型接口、通配符、上下限
- JAVA之旅(二十一)——泛型的概述以及使用,泛型类,泛型方法,静态泛型方法,泛型接口,泛型限定,通配符
- JAVA之旅(二十一)——泛型的概述以及使用,泛型类,泛型方法,静态泛型方法,泛型接口,泛型限定,通配符
- JAVA基础再回首(十六)——泛型的概述、使用、泛型类、泛型方法、泛型接口、泛型高级(通配符)
- 【Java】关于泛型:泛型类、泛型接口和泛型方法
- Java基础----Java---集合框架---泛型、泛型方法、静态方法泛型、泛型接口、泛型限定、泛型类
- [疯狂Java]泛型:类型参数多态问题、类型通配符(?)、类型通配符的上下限、类型参数的上限(类、接口)
- Java基础学习之泛型(泛型方法、泛型类、通配符的使用)
- [Java 10 泛型] 泛型通配符 Info<?> i = new Info<String>(); 在程序中定义没有方法的接口,称之为标识接口
- 【7】Java泛型:泛型类、泛型接口、泛型方法
- java 泛型详解(普通泛型、 通配符、 泛型接口,泛型数组,泛型方法,泛型嵌套)
- Java笔记 – 泛型 泛型方法 泛型接口 擦除 边界 通配符
- java语言基础(69)——集合框架(泛型的多种应用场景、泛型类、泛型方法、泛型接口)
- java 泛型 -- 泛型类,泛型接口,泛型方法
- java学习第十八天之泛型、ArrayList、TreeSet、HashSet、泛型方法,泛型接口、泛型类、泛型的限定
- Java基础----Java---集合框架---泛型、泛型方法、静态方法泛型、泛型接口、泛型限定、泛型类
- java 泛型详解(普通泛型、 通配符、 泛型接口,泛型数组,泛型方法,泛型嵌套)
- [Java 10 泛型] 泛型通配符 Info<?> i = new Info<String>(); 在程序中定义没有方法的接口,称之为标识接口