java day024 泛型
1.为什么需要泛型
当我们需要重复使用一段程序执行逻辑相同而数据类型不同的代码时,为了避免方法的冗余,就需要泛型这个概念!
2.泛型在方法中的使用
格式:
权限修饰符 [static] <自定义泛型> 返回值类型 方法名(形式参数列表){
}
重点:
- 要求形参列表中必须有一个参数是当前自定义泛型,因为需要通过参数来约束当前程序自定义泛型的具体数据类型
- 返回值可以使用自定义泛型,不过被形参列表中传入的泛型所对应的具体数据类型约束
- 方法体内也可以使用自定义泛型,同样被传参中泛型所对应的自定义泛型约束
/** 自定义泛型在方法中的使用
*
* @author Arkay
*
*/
public class TestGenerics {
public static void main(String[] args) {
Integer a = getType(1);
String s = getType("hallo world");
TestGenerics testGenerics = getType(new TestGenerics());
Exception exception = getType(new Exception());
}
/**
* 带有自定义泛型的方法
*
* @param <T> 自定义泛型无意义大写单个英文字母占位符
* @param t T类型
* @return T类型
*/
public static <T> T getType(T t) {
return t;
}
}
自定义泛型使用案例:
/**
* 泛型在方法中的使用
* @author Arkay
*
*/
public class TestGenerics1 {
public static void main(String[] args) {
printEverthing(1);
printEverthing("hello world");
printEverthing('我');
System.out.println("----------------------------");
Integer[] i = {1, 3, 5, 7, 8};
printArray(i);
System.out.println();
printArray(new String[10]);
}
/**
* 用泛型来打印输出任何数据类型
* @param <T> 无意义大写单个英文字母占位符 用来表示泛型
* @param t 任意数据类型
*/
public static <T> void printEverthing(T t) {
System.out.println(t);
}
/**
* 用泛型来展示数组元素
* @param <T> 无意义大写单个英文字母占位符 用来表示泛型
* @param arr 任意数组
*/
public static <T> void printArray(T[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
/*
输出结果:
1
hello world
我
----------------------------
1 3 5 7 8
null null null null null null null null null null
*/
3.泛型在类中的使用
格式:
class 类名<自定义泛型> {
//成员常量不推荐使用泛型,存在隐患
//成员方法可以使用类声明时的自定义泛型
//静态成员方法不能使用类声明的自定义泛型
}
类名使用泛型约束具体数据类型的格式:
class A {
}
Eclipse:
类名<具体数据类型> 类对象名 = new 构造方法<具体数据类型>();
例:
A a = new A();
IDEA:
类名<具体数据类型> 类对象名 = new 构造方法<>();
例:
A a = new A<>();
代码案例:
/**
* 自定义泛型类
* @author Arkay
*
* @param <T> 无意义的单个大写英文字母占位符 表示泛型
*/
class A<T> {
/**
* 功能:打印输出被约束的具体数据类型值
* @param t 声明中的数据类型值
*/
public void test(T t) {
System.out.println(t);
}
/**
* 返回被约束的具体数据类型值
* @param t 声明中的数据类型值
* @return 返回t
*/
public T test2(T t) {
return t;
}
}
public class TestGenerics2 {
public static void main(String[] args) {
//用Integer约束泛型,类的成员方法的泛型都是Integer类型
A<Integer> a = new A<Integer>();
a.test(1);
System.out.println(a.test2(10));
//用String约束泛型,类的成员方法的泛型都是String类型
A<String> a2 = new A<String>();
a2.test("hello world");
System.out.println(a2.test2("HELLO WORLD"));
}
}
/*
输出结果:
1
10
hello world
HELLO WORLD
*/
小总结:
- 类内的成员方法可以直接使用对应的类声明泛型
- 类内成员方法使用的泛型具体数据类型由创建当前对象时约束
- 若创建对象未约束具体类型,则默认为Object类型,有悖于泛型使用原则
为什么静态成员方法不能使用类声明的自定义泛型
类泛型约束的具体数据类型是在类对象声明的时候确定的,而静态成员方法则是在类加载的时候就需要明确所有内容。生存周期不合理!
4. 泛型在接口中的使用
格式:
interface 接口名<自定义泛型> {
自定义泛型有且只能给方法使用
}
带有泛型的接口实现的两种方式:
/**
* 自定义泛型接口
* @author Arkay
*
* @param <T> 泛型
*/
interface E<T> {
T test(T t);
}
/**
* 实现类与接口相同泛型,泛型对应的具体数据在对象声明时明确
*
* @author Arkay
*
* @param <T>
*/
class TypeA<T> implements E<T> {
@Override
public T test(T t) {
System.out.println("未明确自定义泛型!");
return t;
}
}
/**
* 实现类在实现接口时,接口的泛型已明确具体数据类型
*
* @author Arkay
*
*/
class TypeB implements E<String> {
@Override
public String test(String t) {
// TODO Auto-generated method stub
return "哈哈";
}
}
public class TestGenerics3 {
public static void main(String[] args) {
TypeA<Integer> typeA = new TypeA<Integer>();
typeA.test(1);
TypeB typeB = new TypeB();
typeB.test("嘿嘿");
}
}
转载:https://blog.csdn.net/weixin_43684474/article/details/106107460
查看评论