8.javaSE基础进阶_泛型generics(无解通配符?+上下界统配符super&extends)

文章目录

泛型generics

一.泛型简介

JDK5引入,一种安全机制,编译时检测不匹配类型

  1. 特点:
    • 将数据类型作为参数传递
    • 编译时检查类型是否匹配
    • 所有强制转换都是自动和隐私的
    • 安全机制,提高代码复用率
java 复制代码
[访问修饰符] class 类名<T,U,...> {
    T 泛型成员1 ;
    U 泛型成员2;
    ...
}
//..................................
public instance Generics<T,K>{//大写表示数据类型,小写代表变量|参数
   List<T> employee;
   T queryAll();
   T add(T,t);
  int update(K,k);
}
  1. 常用泛型标识符:

    通配符 说明
    T (type) 表示具体的一个java类
    K V (key value) 分别代表java键值中的Key Value
    E (element) 一般在集合中使用,表示集合中的元素类型
    表示不确定的 java 类型,经常出现在集合类中

本质泛型就是通配符, 替代数据

二.泛型类

访问修饰符 class 类名<T,U,...> {

T 泛型成员1 ;

U 泛型成员2;

...

}

//类型参数使用大写形式

1.泛型方法

泛型方法,是在调用方法的时候指明泛型的具体类型

三.泛型接口

java 复制代码
public interface IBaseDao <T,K>{//T表示Employee类,K表示Integer类
    List<T> queryAll();
    int add(T t) throws IOException;
    int updateById(T t);
    int del(K k);
    T queryById(K k) ;
}
//IDeptDao接口继承泛型接口,使用其方法,自己内部方法省略,申明自己的泛型类型替代IBaseDao接口的T,K
public interface IDeptDao extends IBaseDao<Dept,Integer> {
//    List<Dept> quarryAll();
//
//    int addDept(Dept dept);
//
//    int updateByIdDept(Dept dept);
//
//    int quarryByIdDept(int id);
//
//    int delDept(int id);
}

接口名末尾对泛型进行申明,用一个泛型接口规范实现类的操作

四.泛型进阶

除了用 <T> 表示泛型外,还有 <?> 这种形式。<?> 被称作无限定的通配符

1.++<?>无解通配符++

T 是一个确定的类型,通常用于泛型类和泛型方法的定义。

?是一个不确定的类型,通常用于泛型方法的调用代码和形参,不能用于定义类和泛型方法

static Class<?>返回类型 forName(String className) 返回与给定字符串名称的类或接口相关联的 类对象。

List<?>是一个未知类型的List,不能向List<?>中添加元素,但可以把List<String>List<Integer>赋值给List<?>

List<?>List<Object >是不一样的,<Object>表示任意类型,<?>表示未知类型,可以向List<Object>中添加元素,但是不能把List<String>赋值给List<Object>

java 复制代码
public class MainApp {
	public static void main(String[] args) {
		List<Integer> intlist = new ArrayList<Integer>();
		intlist.add(11);
		intlist.add(22);
		intlist.add(33);
    	printList(strList);
        //
		List<String> strList = new ArrayList<String>();
		strList.add("aa");
		strList.add("bb");
		strList.add("cc");
		printList(strList);
	}
  //不确定调用方法时传递的参数是什么类型,用?替代数据类型
	private static void printList(List<?> list) {
		for (Object obj : list) {
			System.out.println(obj);
		}	
	}
}

2.上界通配符 < ? extends E>

java 复制代码
package com.woniuxy.generate;

import java.util.ArrayList;
import java.util.List;
//测试
public class MainApp {
	public static void main(String[] args) {
		List<Apple> applelist = new ArrayList<Apple>();
		applelist.add(new Apple());
		applelist.add(new Apple());
		applelist.add(new Apple());
		List<String> strList = new ArrayList<String>();
		strList.add("aa");
		strList.add("bb");
		strList.add("cc");
		printList(applelist);
	}
//  定义一个方法,可以接收Fruit,以及Fruit所有的子类的集合元素
	private static void printList(List<? extends Fruit> list) {
		for (Object obj : list) {
			System.out.println(obj);
		}	
	}
//定义一个Fruit类    
    class Fruit {
        public void eat() {
            System.out.println("eat fruit");
        }
        @Override
        public String toString() {
            return "Fruit []";
        }	
  }
  //定义一个Fruit的子类Apple
    class Apple extends Fruit {
        private String name;
        @Override
        public String toString() {
            return "Apple []";
        }
	}
}
//代码解析:
//< ? extends E>, E表示父类Fruit,表示继承父类Fruit的元素或者父类Fruirt的参数传递,否则编译不成功
//入的类型是 E 或者 E 的子类

3.下界通配符 < ? super E>

返回类型 方法
Class<? super E> getSuperclass() 返回 类表示此所表示的实体(类,接口,基本类型或void)的超类 类(父类||父类上面的类) 。
java 复制代码
/**
 *  定义一个方法,可以接收Apple,以及Apple所有的父类集合
 * 传递参数是Apple || Apple的父类
 * @param list 
 */
private static void printList(List<? super Apple> list) {
	for (Object obj : list) {
		System.out.println(obj);
	}	
}

4.泛型擦除

泛型实现方式是擦拭法(Type Erasure)

复制代码
    //通过java反射的方式可以绕过泛型,
	Class<? extends List> clazz = intList.getClass();
	Method method = clazz.getMethod("add", Object.class);
	method.invoke(intList, "hello");
复制代码
    //通过java反射的方式可以绕过泛型,
	Class<? extends List> clazz = intList.getClass();
	Method method = clazz.getMethod("add", Object.class);
	method.invoke(intList, "hello");
	System.out.println(intList);
相关推荐
牧瀬クリスだ7 分钟前
深入解析wait与notify及多线程实战案例
java
x***r1518 分钟前
Node.js v0.12.2 安装教程(Windows x86版 node-v0.12.2-x86.msi 详细步骤)
windows·node.js
AI人工智能+电脑小能手8 分钟前
【大白话说Java面试题 第97题】【Mysql篇】第27题:说说分库与分表的设计?
java·开发语言·数据库·分布式·mysql·算法
2301_7926748615 分钟前
java学习(day37)
java
洒脱的六边形战士加辣17 分钟前
Java排序方法全解析
java·数据结构·算法
ofoxcoding19 分钟前
MiniMax M3 实测手记:踩完坑之后,我总结了报错处理和省 token 的几个办法
java·前端·人工智能·ai
Python+9920 分钟前
线程创建、生命周期、线程池
java
ch.ju26 分钟前
Java Programming Chapter 4——The set-get method.
java·开发语言
段ヤシ.30 分钟前
回顾Java知识点,面试题汇总Day12:tomcat、 Java Web(持续更新)
java·前端·tomcat·java web
JAVA学习通31 分钟前
从 Bean 到微服务:一张图吃透 Spring 全家桶底层原理
java·前端·spring