Java泛型详解:提升代码安全与效率
·
第十五章:泛型
泛型
好处:
- 编译时,检查添加元素的类型,提高安全性
- 减少了类型转换的次数,提高效率
不使用泛型:
Dog - 加入 - > Object - 取出 - > Dog
使用泛型:
Dog - 加入 - > Dog - 取出 - > Dog
介绍:
使用:
package com.lcz.generic;
import java.util.*;
/**
* @author lcz
* @version 1.0
* 需求:
* 泛型举例使用
* 1.创建3个对象
* 2.将学生对象放入到HashSet中
* 3.放入到HashMap中,要求Key是String name、Value是学生对象
* 4.使用两种方式遍历
*/
public class Generic {
public static void main(String[] args) {
//1.HashSet
HashSet<Student> students = new HashSet<>();
students.add(new Student("lhc",24));
students.add(new Student("lcz",20));
students.add(new Student("wdm",20));
//迭代器遍历
System.out.println("迭代器遍历");
Iterator<Student> iterator = students.iterator();
while (iterator.hasNext()) {
Student student = iterator.next();
System.out.println(student);
}
//增强for
System.out.println("增强for");
for (Student student :students) {
System.out.println(student);
}
//2.HashMap
HashMap<String, Student> hm = new HashMap<>();
hm.put("lhc",new Student("lhc",24));
hm.put("lcz",new Student("lcz",20));
hm.put("wdm",new Student("wdm",20));
//获取entry集合
Set<Map.Entry<String, Student>> entries = hm.entrySet();
//迭代器遍历
System.out.println("迭代器遍历");
Iterator<Map.Entry<String, Student>> iterator1 = entries.iterator();
while (iterator1.hasNext()) {
Map.Entry<String, Student> student = iterator1.next();
System.out.println(student);
}
//增强for
System.out.println("增强for");
for (Map.Entry entry :entries) {
System.out.println(entry.getKey() + " : " + entry.getValue());
}
}
}
class Student{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
自定义泛型
自定义泛型类
语法:
class 类名<T,R...>{//...表示可以有多个泛型
成员
}
细节:
1.普通成员可以使用泛型(属性、方法)
2.使用泛型的数组,不能初始化
因为数组在new 不能确定T的类型,就无法在内存开辟空间
3.静态方法中不能使用类的泛型
因为静态是和类相关的,在类加载时,对象还没有创建
所以,如果静态方法和静态属性使用了泛型,JVM就无法完成初始化
4.创建对象时需指定泛型类的类型
若没有指定,默认为Object
package com.lcz.generic.customgeneric;
import java.util.ArrayList;
/**
* @author lcz
* @version 1.0
* 需求:
* 自定义泛型类
*
*/
public class CustomGeneric {
public static void main(String[] args) {
A<String, Integer, Double> lhc = new A<String, Integer, Double>("lhc", 24, 2000.0);
System.out.println(lhc);
}
}
class A<T,R,M>{
private T t;//属性使用泛型
private R r;
private M m;
public A(T t, R r, M m) {//参数使用泛型
this.t = t;
this.r = r;
this.m = m;
}
public T getT() {//方法返回值使用泛型
return t;
}
public void setT(T t) {
this.t = t;
}
public R getR() {
return r;
}
public void setR(R r) {
this.r = r;
}
public M getM() {
return m;
}
public void setM(M m) {
this.m = m;
}
@Override
public String toString() {
return "A{" +
"t=" + t +
", r=" + r +
", m=" + m +
'}';
}
}
自定义泛型接口

语法:
interface 接口名<T,R...>{
}
细节:
1.静态成员不能使用泛型
2.泛型接口的类型,在继承接口或者实现接口时确定
3.没有指定类型,默认为Object
package com.lcz.generic.customgeneric;
/**
* @author lcz
* @version 1.0
* 需求:
* 自定义泛型接口
*/
public class CustomGeneric01 {
public static void main(String[] args) {
}
}
interface IUsb<T,R>{
void f1(T t,R r);
}
interface IA extends IUsb<String,Integer>{
}
class A1 implements IUsb<String,Double>{
@Override
public void f1(String s, Double aDouble) {
}
}
class B1 implements IA{
@Override
public void f1(String s, Integer integer) {
}
}
自定义泛型方法

语法:
修饰符<T,R...> 返回类型 方法名(参数列表){
}
细节:
1.泛型方法,可以定义在普通类中,也可以定义在泛型类中
2.当泛型方法被调用时,类型也会确定
3.public void eat(E e){},修饰符后没有<T,R...>,eat方法不是泛型方法,而是使用了泛型
package com.lcz.generic.customgeneric;
/**
* @author lcz
* @version 1.0
* 需求:
* 自定义泛型方法
*/
public class CustomGeneric03 {
public static void main(String[] args) {
new C().f1("saf",10);
System.out.println("=====");
new C().f1('f',10.0);
}
}
class C{
public <T,R> void f1(T t,R r){
System.out.println(t.getClass().getSimpleName());
System.out.println(r.getClass().getSimpleName());
}
}
泛型的继承和通配符

细节:
1.泛型不具备继承性
ArrayList<Object> alt = new ArrayList<String>()//不具备继承性,会报错
2.<?>:支持任意泛型类型
3.<? extends A>:支持A类以及A类的子类,规定了泛型的上限
4.<? super A>:支持A类以及A类父类,规定了泛型的下限
package com.lcz.generic.customgeneric.extend;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
/**
* @author lcz
* @version 1.0
* 需求:
* 泛型的继承和通配符
*/
public class Extends_ {
public static void main(String[] args) {
ArrayList<String> strings = new ArrayList<>();
ArrayList<Integer> integers = new ArrayList<>();
ArrayList<AA> aas = new ArrayList<>();
ArrayList<BB> bbs = new ArrayList<>();
ArrayList<CC> ccs = new ArrayList<>();
printCollection1(aas);
}
public static void printCollection(List<?> c){
for (Object o :c) {
System.out.println(o);
}
}
public static void printCollection1(List<? extends AA> c){
for (Object o :c) {
System.out.println(o);
}
}
public static void printCollection2(List<? super AA> c){
for (Object o :c) {
System.out.println(o);
}
}
}
class AA{
}
class BB extends AA{
}
class CC extends BB{
}
本章作业

package com.lcz.generic.customgeneric.homework;
import org.junit.jupiter.api.Test;
import java.util.*;
/**
* @author lcz
* @version 1.0
* 需求:
* 定义一个泛型类DAO<T>,在其中定义一个Map成员变量,Map的键为String类型,值为T类型
* 分别创建一下方法:
* (1):public void save(String id,T entity):保存T类型的对象到Map成员变量中
* (2):public T get(String id):从map中获取id对应的对象
* (3):public void update(String id,T entity):替换map中key为id 的内容,改为entity对象
* (4):public List<T> list():返回map中存放的所有T对象
* (5):public void delete(String id):删除指定id对象
*
* 定义一个User类:
* 包含:int id,age;String name;
* 创建DAO类的对象,分别调用其save、get、update、list、delete方法来操作User对象,
* 使用JUnit单元测试类进行测试
*/
public class Homework01 {
public static void main(String[] args) {
}
@Test
public void testList(){
DAO<User> userDAO = new DAO<User>();
userDAO.save("1",new User(1,24,"lhc"));
System.out.println(userDAO.get("1"));
userDAO.update("1",new User(2,20,"lcz"));
List<User> list = userDAO.list();
for (User user :list) {
System.out.println(user);
}
userDAO.delete("1");
}
}
class DAO<T>{
private Map<String,T> map = new HashMap<>();
public void save(String id, T entity){
map.put(id,entity);
}
public T get(String id){
return map.get(id);
}
public void update(String id,T entity){
map.put(id,entity);
}
public List<T> list(){
Collection<T> values = map.values();
return new ArrayList<>(values);
}
public void delete(String id){
map.remove(id);
}
}
class User{
private int id;
private int age;
private String name;
public User(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", age=" + age +
", name='" + name + '\'' +
'}';
}
}
更多编程学习资源
编程学习公众号【程序员论周】
更多推荐




所有评论(0)