脑中要构想出连贯的动画,一切都是以这个动画为基础的;然后给别人讲明白
泛型
-
理解:
其本质是 参数化类型,也就是说所操作的数据类型被指定为一个参数(type parameter)这种参数类型可以用在类、接口和方法的创建中,分别称为 泛型类、泛型接口、泛型方法。 -
泛型类、泛型接口demo演示;注意:静态方法上不能直接使用类上定义的泛型;静态方法中可以使用方法上定义的泛型
public class GenricMethod<K,V> {
/**
* 1、实体方法使用类上定义的泛型
* @param k
* @param v
* @return
*/
public K method1(K k,V v){
return null;
}
public <T> T method02(){ //2、方法上定义泛型
return null;
}
/**
* 静态方法中不能直接使用类上定义的泛型
* 静态方法中可以使用方法上定义的泛型
* @return
*/
// public static V method03(){
// return null;
// }
public static <P> P method04(){
return null;
}
}
- 泛型接口,可以参照mybatis-plus的BaseService和BaseMapper的实现
public interface CalGenneric <T>{
T add(T a,T b);
T sub(T a,T b);
T mul(T a,T b);
T div(T a,T b);
}
public class DoubleCalc<Double> implements CalGenneric<Double>{
@Override
public Double add(Double a, Double b) {
return null;
}
@Override
public Double sub(Double a, Double b) {
return null;
}
@Override
public Double mul(Double a, Double b) {
return null;
}
@Override
public Double div(Double a, Double b) {
return null;
}
}
public class IntCal implements Cal {
@Override
public int add(int a, int b) {
return 0;
}
public double add(double a, double b) {
return 0;
}
@Override
public int sub(int a, int b) {
return 0;
}
@Override
public int mul(int a, int b) {
return 0;
}
@Override
public int div(int a, int b) {
return 0;
}
}
- 泛型的通配符:
- 无界通配符 ? 【相当于Object】
- 上界通配符 ?extends Number 【只能比Number小的】
- 下界通配符 ? super Integer 【只能比Integer大的】
- 泛型的作用:Java泛型保障了类型的安全;避免了类型转换逻辑;提高代码的重用率;
- 伪泛型,Java编译期间会将泛型擦除
- 堆污染:当一个可变泛型的参数指向了一个无泛型参数可能发生的现象叫堆污染。
java泛型详解(接口与方法、通配符、堆污染、多态—含代码!) - 泛型桥接(编译看左边,运行看右边)
public interface SuperClass<T> {
T m01(T param);
}
public class SubClass implements SuperClass<String> {
@Override
public String m01(String param) {
return param + "---";
}
}
public class BridgeMethosTest {
public static void main(String[] args) {
SuperClass subClass = new SubClass(); // 多态
System.out.println(subClass.m01("123abc"));
System.out.println(subClass.m01(new Object())); //mo1(object)
}
}
使用javap -v SubClass.class 查看字节码文件,会看到子类中的方法m01存在两个,如下图,一个形参是String类型,另一个是Object类型。object的方法 flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC,此处是编译器自动生成的方法。 整个流程大概是对象调用泛型Object形参的方法,object的m01方法又调用了String的方法导致报错。【 5: invokevirtual #8 // Method m01:(Ljava/lang/String;)Ljava/lang/String;】
Last modified 2021-8-2; size 975 bytes
MD5 checksum 149a338e69adb923b1b205f45d13437a
Compiled from “SubClass.java”
public class com.nx.vip.javacore.generic.bridge.SubClass extends java.lang.Object implements com.nx.vip.javacore.generic.bridge.SuperClass<java.lang.String>
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #10.#29 // java/lang/Object.""😦)V
#2 = Class #30 // java/lang/StringBuilder
#3 = Methodref #2.#29 // java/lang/StringBuilder.""😦)V
#4 = Methodref #2.#31 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#5 = String #32 // —
#6 = Methodref #2.#33 // java/lang/StringBuilder.toString:()Ljava/lang/String;
#7 = Class #34 // java/lang/String
#8 = Methodref #9.#35 // com/nx/vip/javacore/generic/bridge/SubClass.m01:(Ljava/lang/String;)Ljava/lang/String;
#9 = Class #36 // com/nx/vip/javacore/generic/bridge/SubClass
#10 = Class #37 // java/lang/Object
#11 = Class #38 // com/nx/vip/javacore/generic/bridge/SuperClass
#12 = Utf8
#13 = Utf8 ()V
#14 = Utf8 Code
#15 = Utf8 LineNumberTable
#16 = Utf8 LocalVariableTable
#17 = Utf8 this
#18 = Utf8 Lcom/nx/vip/javacore/generic/bridge/SubClass;
#19 = Utf8 m01
#20 = Utf8 (Ljava/lang/String;)Ljava/lang/String;
#21 = Utf8 param
#22 = Utf8 Ljava/lang/String;
#23 = Utf8 MethodParameters
#24 = Utf8 (Ljava/lang/Object;)Ljava/lang/Object;
#25 = Utf8 Signature
#26 = Utf8 Ljava/lang/Object;Lcom/nx/vip/javacore/generic/bridge/SuperClass<Ljava/lang/String;>;
#27 = Utf8 SourceFile
#28 = Utf8 SubClass.java
#29 = NameAndType #12:#13 // “”😦)V
#30 = Utf8 java/lang/StringBuilder
#31 = NameAndType #39:#40 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#32 = Utf8 —
#33 = NameAndType #41:#42 // toString:()Ljava/lang/String;
#34 = Utf8 java/lang/String
#35 = NameAndType #19:#20 // m01:(Ljava/lang/String;)Ljava/lang/String;
#36 = Utf8 com/nx/vip/javacore/generic/bridge/SubClass
#37 = Utf8 java/lang/Object
#38 = Utf8 com/nx/vip/javacore/generic/bridge/SuperClass
#39 = Utf8 append
#40 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder;
#41 = Utf8 toString
#42 = Utf8 ()Ljava/lang/String;
{
public com.nx.vip.javacore.generic.bridge.SubClass();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object.""😦)V
4: return
LineNumberTable:
line 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/nx/vip/javacore/generic/bridge/SubClass;
public java.lang.String m01(java.lang.String);
descriptor: (Ljava/lang/String;)Ljava/lang/String;
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=2
0: new #2 // class java/lang/StringBuilder
3: dup
4: invokespecial #3 // Method java/lang/StringBuilder.""😦)V
7: aload_1
8: invokevirtual #4 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
11: ldc #5 // String —
13: invokevirtual #4 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
16: invokevirtual #6 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
19: areturn
LineNumberTable:
line 6: 0
LocalVariableTable:
Start Length Slot Name Signature
0 20 0 this Lcom/nx/vip/javacore/generic/bridge/SubClass;
0 20 1 param Ljava/lang/String;
MethodParameters:
Name Flags
param
public java.lang.Object m01(java.lang.Object);
descriptor: (Ljava/lang/Object;)Ljava/lang/Object;
flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
Code:
stack=2, locals=2, args_size=2
0: aload_0
1: aload_1
2: checkcast #7 // class java/lang/String
5: invokevirtual #8 // Method m01:(Ljava/lang/String;)Ljava/lang/String;
8: areturn
LineNumberTable:
line 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 this Lcom/nx/vip/javacore/generic/bridge/SubClass;
MethodParameters:
Name Flags
param synthetic
}
Signature: #26 // Ljava/lang/Object;Lcom/nx/vip/javacore/generic/bridge/SuperClass<Ljava/lang/String;>;
SourceFile: “SubClass.java”