package com.generic;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Test {
public static void main(String[] args){
useTool();
System.out.println();
useSpecTool();
System.out.println();
useSpecFun();
System.out.println();
useSpecSuperFun();
System.out.println();
useSpecComFun();
System.out.println();
useSpecStaticFun();
System.out.println();
useInterFun();
System.out.println();
useHighLevelFun();
}
/**
* 泛型出现之前只好使用Object,具体使用时必须要强制类型转换
* 极有可能出现转换类型错误这种运行时异常
*/
public static void useTool(){
try{
Tool tool = new Tool();
tool.setObj(new Teacher());
Teacher tea = (Teacher)tool.getObj();
System.out.println(tea.print());
//这里将出现运行时异常
Student stu = (Student)tool.getObj();
}catch(Exception e){
System.out.println("出错!");
}
}
public static void useSpecTool(){
//使用泛型之后可以提早发现出错源头,提高安全性
//注意,只能对引用数据类型不确定时使用,基本类型无效(只针对对象)
SpecTool<Teacher> sepcTool = new SpecTool<Teacher>();
sepcTool.setObj(new Teacher());
Teacher tea = sepcTool.getObj();
System.out.println(tea.print());
//使用泛型之后将产生编译时错误,可及早发现
//sepcTool.setObj(new Student());
}
public static void useSpecFun(){
//使用泛型,制定之后即可在方法中使用
SpecFun<Integer> fun = new SpecFun<Integer>();
fun.show(100);
fun.print(3232);
//使用错误的类型将会导致编译时异常
//fun.show("shit");
}
public static void useSpecSuperFun(){
SpecSuperFun fun = new SpecSuperFun();
//使用泛型方法,可以单独为每个方法制定不同的输入类型
fun.show("ddddddd");
fun.show(new Teacher());
fun.show(100);
fun.print(new Student());
}
public static void useSpecComFun(){
SpecComFun<String> fun = new SpecComFun();
fun.show("ddddddd");
//一旦指定了泛型类,则使用了类指定泛型的方法只能使用该类型,否则将产生编译时错误
//fun.show(new Teacher());
//而没有指定类泛型的方法可以任意使用任何类型
fun.print(new Student());
fun.print(200);
}
public static void useSpecStaticFun(){
SpecStaticFun<String> fun = new SpecStaticFun();
fun.show("ddddddd");
//静态方法可以直接使用类调用,所以静态方法的泛型必须指定为泛型方法
SpecStaticFun.print("sssss");
SpecStaticFun.print(new Teacher());
}
public static void useInterFun(){
//使用已经指定类型的实现类,则具体使用时的类型必须和实现的类型一样,否则出编译时错误
//Inter<Integer> inter = new InterImpl();
Inter<String> inter = new InterImpl();
inter.show("22222");
//继承类也可以不指定实现的类型,这样就可以在具体使用时自由指定
Inter<Integer> inter2 = new InterImpl2<Integer>();
Inter<Teacher> inter3 = new InterImpl2<Teacher>();
}
public static void useHighLevelFun(){
List<String> l1 = new ArrayList<String>();
l1.add("l-111");
l1.add("l-222");
List<High> high = new ArrayList<High>();
high.add(new High());
high.add(new High());
List<Middle> middle = new ArrayList<Middle>();
middle.add(new Middle());
middle.add(new Middle());
List<Low> low = new ArrayList<Low>();
low.add(new Low());
low.add(new Low());
high.add(new Low());
//直接的?可以接受任意类型
print(l1);
print2(l1);
print(high);
print(middle);
print(low);
//? extends T 可以接受T以及T的所有子类
//print3(high); //编译期错误
print3(middle);
print3(low);
//? super T 可以接受T以及T的所有父类
print4(high);
print4(middle);
//print4(low); //编译期错误
}
//不明确传入的类型的时候可以使用“?”占位符,仅仅作为站位用
//这样就表示任何传入的list都可以接受
private static void print(List<?> list){
Iterator<?> it = list.iterator();
while(it.hasNext()){
System.out.print(it.next() + " ");
}
System.out.println();
}
//使用这种方法的话就可以在方法中具体使用“T”类型,但是“?”占位符的方法就不可以
private static <T> void print2(List<T> list){
Iterator<T> it = list.iterator();
while(it.hasNext()){
System.out.print(it.next() + " ");
}
System.out.println();
}
//通配符向上限定,可以接受Middle类或者Middle类的子类
private static void print3(List<? extends Middle> list){
Iterator<? extends Middle> it = list.iterator();
while(it.hasNext()){
System.out.print(it.next() + " ");
}
System.out.println();
}
//通配符向下限定,可以接受Middle类或者Middle类的子类
private static void print4(List<? super Middle> list){
Iterator<? super Middle> it = list.iterator();
while(it.hasNext()){
System.out.print(it.next() + " ");
}
System.out.println();
}
}
class Teacher{
public String print(){
return "TTTTTTT";
}
public String toString(){
return "Teacher!!!!!";
}
}
class Student{
public String print(){
return "SSSSSSS";
}
public String toString(){
return "Student!!!!!";
}
}
/**
* 出现泛型之前的做法,使用Object
*/
class Tool{
private Object obj;
public final Object getObj() {
return obj;
}
public final void setObj(Object obj) {
this.obj = obj;
}
}
/**
* 泛型类:
* 使用泛型,由使用者决定使用什么类型
* 尖括号里面的命名可以随便起
*/
class SpecTool<BalaBala>{
private BalaBala obj;
public final BalaBala getObj() {
return obj;
}
public final void setObj(BalaBala obj) {
this.obj = obj;
}
}
/**
* 泛型类定义的类型,在整个类之中都有效,如果被方法使用
* 一旦指定,则所有方法要操作的类型则已经指定
*/
class SpecFun<T>{
public void show(T t){
System.out.println("show:" + t);
}
public void print(T t){
System.out.println("print:" + t);
}
}
/**
* 泛型方法:
* 如果使用泛型方法,则可以让不同的方法使用不同的类型
* 具体针对某个方法使用泛型的时候有,可以在每个方法上加上泛型
* 尖括号中的泛型命名依然可以随便制定
* 注意:泛型符号放在返回值类型之前!!
*/
class SpecSuperFun{
public <T> void show(T t){
System.out.println("show:" + t);
}
public <SHIT> void print(SHIT t){
System.out.println("print:" + t);
}
}
/**
* 还可以同时使用泛型类和泛型方法,并不会产生问题
* 注意:泛型符号放在返回值类型之前!!
*/
class SpecComFun<T>{
public void show(T t){
System.out.println("show:" + t);
}
public <SHIT> void print(SHIT t){
System.out.println("print:" + t);
}
}
/**
* 静态泛型方法:
* 注意:静态方法不可以使用类定义的泛型
* 因为类未被实例化的时候,其泛型类型还未被指定,静态方法不能使用未确定的类型
* 所以静态方法的泛型只能在方法上指定
* 注意:泛型符号放在返回值类型之前!!
*/
class SpecStaticFun<T>{
public void show(T t){
System.out.println("show:" + t);
}
public static <SHIT> void print(SHIT t){
System.out.println("print:" + t);
}
}
/**
* 接口定义泛型
*/
interface Inter<T>{
void show(T t);
}
/**
* 第一种应用于接口上的泛型使用方法
* 也即在实现接口的同时就指定泛型的类型
*/
class InterImpl implements Inter<String>{
@Override
public void show(String t) {
System.out.println("hahah show:" + t);
}
}
/**
* 第二中应用与接口上的泛型使用方法
* 也即实现类上面也是用泛型,注意泛型的名字必须要和接口一样
* @author Feng
*
* @param <T>
*/
class InterImpl2<T> implements Inter<T>{
@Override
public void show(T t) {
System.out.println("wulawula show:" + t);
}
}
/**
* 三个类具有连续继承关系,在使用泛型限定(向上or向下)的时候可以:
* 通配符:? (接受所有类型)
* 向上限定:? extends T (仅接受T或者T的子类)
* 向下限定:? super T (仅接受T或者T的父类)
* 例如:
* Student和Worker继承Person
* 1、向上限定:
* TreeSet<Student> TreeSet<Worker> 两个Set都需要排序,都需要比较器,但只需要一个就可以了
* Comparator<Person>
* 也即
* class Comp implements Comparator<Person>
* TreeSet<Student> stu = new TreeSet<Student>(new Comp());
* TreeSet<Worker> stu = new TreeSet<Worker>(new Comp());
* 2、向下限定:
* 链表中需要加入所有的Person
* List<Person> per = new ArrayList<Person>();
* per.addAll(new List<Student>());
* per.addAll(new List<Worker>());
*/
class High{
public String toString() {
return "High!!";
}
}
class Middle extends High{
public String toString() {
return "Middle!!";
}
}
class Low extends Middle{
public String toString() {
return "Low!!";
}
}
Java 泛型编程
最新推荐文章于 2024-06-05 16:56:26 发布