专业的JAVA编程教程与资源

网站首页 > java教程 正文

Java泛型

temp10 2024-11-19 11:37:39 java教程 14 ℃ 0 评论

1 泛型在集合中使用

泛型的概述

Java泛型

JDK1.5新特性。

泛型可以使用在方法中,类上,接口上

泛型在集合中使用的好处

将运行期错误转换为编译器错误,增强了集合的安全性

避免了类型强制转换的麻烦。

泛型在集合中的使用注意事项

泛型中,没有多态的概念,要么指定左边,要么两边都指定相同的数据类型

在JDK1.7之前,必须两边都指定相同的数据类型

示例

import java.util.ArrayList;
public class CollectionDemo {
public static void main(String[] args){
// 创建集合对象
ArrayList<String> list = new ArrayList<>();
list.add(
"AAA");
list.add(
"BBB");
list.add(
"CCC");
// list.add(123);
for(String str:list){
System.
out.println(str.length());
}
// 遍历集合
for (Object obj:list) {
// 向下转型为字符串
String str = (String) obj;
System.
out.println(str.length());
}
}
}

2 泛型的定义与使用

2.1 泛型方法

定义一个方法接收一个任意类型的参数,返回值类型与实际参数类型一致

什么是泛型

数据类型参数化

泛型方法的引入

定义一个方法接收一个任意类型的参数,返回值类型与实际参数类型一致

泛型的概述

JDK1.5新特性。

泛型可以使用在方法中,类上,接口上

泛型变量可以理解为是一种数据类型的占位符

泛型变量还可以理解为一种数据类型的变量

泛型变量的命名规则:只要是合法的标识符就可以,一般会使用一个大写字母表示

常用的泛型变量的名字:T, K, V,E

泛型方法的概念

在定义方法时定义了泛型变量的方法则称为泛型方法

泛型方法的定义格式

修饰符 <T> 返回值类型 方法名(参数列表){}

泛型方法的注意事项

泛型变量的具体数据类型是在调用该方法时由调用者传递参数决定

参数是什么类型,则泛型变量的具体数据类型就是什么类型

泛型变量的具体数据类型不能是基本数据类型,如果要使用基本数据类型,要使用对应的包装类类型

示例

public class Demo {
public static void main(String[] args){
String str =
test("ABC");
Integer in =
test(234);
Student stu =
test(new Student());
int age = 85;
System.
out.println(age);
}
public static void sum(int a,int b){
}
/*
泛型方法
*/
public static <T> T test(T param){
return param;
}
}

2.2 泛型类

什么是泛型类

在类定义时定义了泛型变量的类就是泛型类

泛型类的定义格式

class 类名<T>{

// 可以将泛型变量T当成一种数据类型使用

}

泛型类的注意事项

泛型变量的具体数据类型是由创建对象时由使用者决定,如果没有指定具体数据类型则默认是Object

静态方法不能使用类上定义的泛型变量,如果该方法要使用泛型变量,则需要将该方法定义为泛型方法

示例

/**

泛型类定义

*/

public class MyArrays<T> {
// 一个方法的功能是将数组的元素反转
public static <T> void reverse(T[] arr){
for(int i = 0,j = arr.length - 1; i < j; i++,j--){
T temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// 一个方法的功能是将数组的元素反转.
// "[1,2,3,4,5,]"
public String toString(T[] arr){
// 创建可变字符串
StringBuilder sb = new StringBuilder("[");
for(T t:arr){
sb.append(t).append(
",");
}
// 删除最后一个,
sb.deleteCharAt(sb.length()-1);
sb.append(
"]");
return sb.toString();
}
public void xxx(){
}
}

public class Demo01 {
public static void main(String[] args) {
// 创建字符串数组
String[] strs = {"a", "b", "c"};
// 创建整型数据
Integer[] arr = {1, 2, 3, 4, 5, 6};
// 创建泛型类对象
MyArrays<String> myArrays01 = new MyArrays<>();
// 此时通过对象myArrays01调用方法,方法中的泛型变量的具体数据类型是:String
myArrays01.reverse(strs);
// 创建泛型类对象
MyArrays<Integer> myArrays02 = new MyArrays<>();
// 此时通过对象myArrays02调用方法,方法中的泛型变量的具体数据类型是:Integer
myArrays02.reverse(arr);
MyArrays myArrays03 =
new MyArrays();
}
}

2.3 泛型接口

什么是泛型接口

在定义接口的同时定义了泛型变量的接口

泛型接口的定义格式

interface 接口名<T>{

// 将泛型变量T当成一种数据类型使用

}

泛型接口的实现方式

方式1:实现接口的同时指定泛型变量的具体数据类型(不推荐使用,不够灵活)

方法2:实现接口时不指定泛型变量的具体数据类型,将实现类定义为泛型类,

由使用者创建泛型类对象时指定泛型变量的具体数据类型。(推荐使用)

示例

/**

Dao:数据访问层接口

泛型接口

?

表现层

业务层

数据访问层:直接跟数据库打交道,对数据库执行增删改查操作的。

*/

public interface Dao<T>{
// 增
public void save(T t);
// 改
public void update(T t);
}

?

/**

实现接口的同时指定泛型变量的具体数据类型

*/

public class ProductDao implements Dao<Product> {
@Override
public void save(Product product) {
System.
out.println("保存产品信息...");
}
@Override
public void update(Product product) {
System.
out.println("更新产品信息...");
}
}

/**

实现接口的同时指定泛型变量的具体数据类型

*/

public class StudentDao implements Dao<Student> {
@Override
public void save(Student student) {
System.
out.println("保存学生信息....");
}
@Override
public void update(Student student) {
System.
out.println("更新学生信息....");
}
}

?

/**

实现接口时不指定泛型变量的具体数据类型,将实现类定义为泛型类,

由使用者创建泛型类对象时指定泛型变量的具体数据类型。

*/

public class BaseDao<T> implements Dao<T> {
@Override
public void save(T t) {
}
@Override
public void update(T t) {
}
}

?

public class Demo02 {
public static void main(String[] args){
// 创建学生对象
Student stu = new Student();
// 创建Dao接口的实现类对象
StudentDao stuDao = new StudentDao();
// 保存学生
stuDao.save(stu);
// 创建产品对象
Product p = new Product();
// 创建Dao接口的实现类对象
ProductDao pdDao = new ProductDao();
// 保存产品
pdDao.save(p);
// 创建BaseDao对象
BaseDao<Student> baseDao01 = new BaseDao<>();
// 保存学生
baseDao01.save(stu);
// 创建BaseDao对象
BaseDao<Product> baseDao02 = new BaseDao<>();
baseDao02.save(p);
}
}

3泛型上下限

3.1 泛型上下限引入

需求一

定义一个方法可以接收任意类型的集合对象

集合对象只能存储Integer或者是Integer的父类数据

需求二

定义一个方法可以接收任意类型的集合对象

集合对象只能存储Number或者是Number的子类数据

3.2 泛型上下限格式

? : 泛型通配符 代表可以匹配任意数据类型。

泛型上限:? extends Number 可以接收Number或Number的子类类型的数据

泛型下限:? super Integer 可以接收Integer或Integer的父类类型的数据

泛型通配符注意事项

? 一般不会单独使用,一般会结合泛型上下限使用

? 不能用来定义泛型方法,泛型类,泛型接口

? 和 泛型变量T 的区别

? 不需要定义就可以使用,T 需要先定义再使用

? 在方法体不能当成一种数据类型使用,泛型变量T可以当成一种数据类型使用

示例

import java.util.ArrayList;
public class Demo03{
public static void main(String[] args){
ArrayList<String> list01 =
new ArrayList<>();
ArrayList<Integer> list02 =
new ArrayList<>();
ArrayList<Object> list03 =
new ArrayList<>();
ArrayList<Number> list04 =
new ArrayList<>();
ArrayList<Long> list05 =
new ArrayList<>();
// test01(list01); 编译失败
test01
(list02);
test01(list03);
test01(list04);
// test02(list01); 编译失败
test02
(list02);
// test02(list03); 编译失败
test02
(list04);
test02(list05);
}
public static void test02(ArrayList<? extends Number> list) {
}
public static void test01(ArrayList<? super Integer> list) {
}
}

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表