网盘做网站,建筑培训网排行榜,广州网站建设要多少钱,建站之星导出网站什么是泛型 泛型就是将类型参数化#xff0c;比如定义了一个栈#xff0c;你必须在定义之前声明这个栈中存放的数据的类型#xff0c;是int也好是double或者其他的引用数据类型也好#xff0c;定义好了之后这个栈就无法用来存放其他类型的数据。如果这时候我们想要使用这…什么是泛型 泛型就是将类型参数化比如定义了一个栈你必须在定义之前声明这个栈中存放的数据的类型是int也好是double或者其他的引用数据类型也好定义好了之后这个栈就无法用来存放其他类型的数据。如果这时候我们想要使用这个栈来存放String字符串类型的数据就需要重写一遍代码并且把数据类型改成String可以说是代码重复性极高。 类型参数化就可以很好的解决这个问题我们在定义栈的时候只需要给一个形参在使用的时候将类型作为参数传递进去就可以使用这个栈来存放不同类型的数据了。 泛型可以使用在接口方法和类里面分别被称为泛型接口泛型方法 java中的泛型标识符 下表是规范用来增强代码的可读性并非必须使用例如在下面的代码中使用了abc照样可以编译运行不过可读性差而且不规范。 下面的例子具体不用弄懂下面会讲解只需要知道abc和****在这里是通配符就好 public static abc void printList(List? extends abc list) {for (abc element : list) {System.out.println(element);}
}标记符含义EElement (在集合中使用因为集合中存放的是元素)TTypeJava 类KKey键VValue值NNumber数值类型可以表示任意类型(或者用来表示未知类型)
有限制的通配符
上限通配符-extends 这些所谓的上和下其实是描述在一个继承关系中的上下关系对于一个类来说它的父类的方向就是上而子类的方向就是下。 所以这里的上限通配符的“上限”指的是一个确定的父类或者一个确定的接口来进行限制该通配符表示的类型都是该父类的子类确定的接口的实现类或者子类的子类(继承关系在这个确定的父类以下的子类或者接口的实现类)
举个栗子
public class AddT extends Number{private T num;Add(T num){this.num num;}
}怎么使用呢
正确调用
AddDouble a new Add(1.1);//正确
AddInteger i new Add(3);//正确错误调用
AddString s new Add(1.1);//错误通过这个例子我们应该就比较好理解了Double和Integer都是Number类的子类所以可以代替“T extends Number”中的T而String不在Number的继承链中所以编译会报错。 虚线下面的类确定的接口和确定的父类就是上限通配符可以表示的类。
下限通配符-super
下限通配符也是一种对泛型类型的限制这里的“下限”指的是继承关系中的类型的下界。
再来一个栗子
这是一个泛型方法 // 泛型方法接受 Number 及其父类的参数static void Generic(List? super Number list) {// 方法体}方法调用 先看一个错误的示例 ListInteger list new ArrayList();Generic(list);下面都是正确的示例 ListNumber list new ArrayList();
Generic(list);ListObject list new ArrayList();
Generic(list); OK从这个例子我们应该很明白啦List? super Number list的尖括号中的数据类型必须是Number及其父类。
多重限定 用来限定类型表示指定的类型参数必须是多个指定类或指定接口的子类。 public class GenericClassT extends ClassA InterfaceB InterfaceC {/***方法和属性*/
}
//表示T必须是ClassA的子类或者子类的子类并且实现了InterfaceB和InterfaceC接口或者实现了接口的类的继承类通过类型参数的限定可以在泛型类或方法中对类型进行更精确的控制和约束以提高代码的类型安全性和灵活性。。 好现在我们已经知道了泛型的常用的标识符了现在我们来了解下泛型的三种应用 泛型类
单元泛型类
class SinglT{ // 这里的标识符可以随意命名T是type的简称 private T var ; public T getVar(){ return var ; } public void setVar(T var){ this.var var ; }
}
public class Generics{ public static void main(String args[]){ SinglString p new SinglString() ; // 里面的var类型为String类型 p.setVar(it is love) ; // 设置字符串 System.out.println(p.getVar().length()) ; // 取得字符串的长度 }
}
多元泛型类
class MultalK,V{ // 这里指定了两个泛型类型 K和V private K key ; //K表示KeyV表示Valueprivate V value ; public K getKey(){ return this.key ; } public V getValue(){ return this.value ; } public void setKey(K key){ this.key key ; } public void setValue(V value){ this.value value ; }
}
public class GenericsClass{ public static void main(String args[]){ MultalString,Integer t ; // 定义两个泛型类型的对象 t new MultalString,Integer() ; // 里面的key为Stringvalue为Integer t.setKey(我爱罗) ; // 设置第一个内容 t.setValue(20) ; // 设置第二个内容 System.out.print(姓名 t.getKey()) ; // 取得信息 System.out.print(年龄 t.getValue()) ; // 取得信息 }
}
语法定义泛型类
class:类名泛型标识1,泛型标识2,泛型标识3.....{ private 泛型标识1 变量名;private 泛型标识2 变量名;
}从泛型类派生子类
派生子类有两种情况
子类如果子类也是泛型类与父类的类型保持一致泛型标识保持一致如果父类没有指明泛型类型则按Object进行处理子类不是泛型类时父类的泛型类型必须指明 例如如果父类没有指明则按照Object操作
子类也是泛型类
示例一单一类型参数的泛型类 如果子类也是泛型类,子类的泛型标识必须和父类保持一致 // 定义一个泛型类
class GenericClassT {private T value;public GenericClass(T value) {this.value value;}public T getValue() {return value;}
}// 从泛型类派生子类子类也是泛型类
class SubGenericClassU extends GenericClassU {public SubGenericClass(U value) {super(value);}public void displayValue() {System.out.println(Value: getValue());}
}// 使用示例
public class Main {public static void main(String[] args) {SubGenericClassString stringInstance new SubGenericClass(Hello, Generics!);stringInstance.displayValue(); // 输出: Value: Hello, Generics!SubGenericClassInteger integerInstance new SubGenericClass(123);integerInstance.displayValue(); // 输出: Value: 123}
}示例 2多个类型参数的泛型类
// 定义一个带有多个类型参数的泛型类
class PairK, V {private K key;private V value;public Pair(K key, V value) {this.key key;this.value value;}public K getKey() {return key;}public V getValue() {return value;}
}// 从泛型类派生子类子类也是泛型类
class ExtendedPairK, V extends PairK, V {public ExtendedPair(K key, V value) {super(key, value);}public void display() {System.out.println(Key: getKey() , Value: getValue());}
}// 使用示例
public class Main {public static void main(String[] args) {ExtendedPairString, Integer pair new ExtendedPair(Age, 30);pair.display(); // 输出: Key: Age, Value: 30ExtendedPairDouble, String anotherPair new ExtendedPair(3.14, Pi);anotherPair.display(); // 输出: Key: 3.14, Value: Pi}
}
子类不是泛型类
定义一个泛型类
子类不是泛型类时父类的泛型类型必须指明
// 定义一个泛型类
class GenericClassT {private T value;public GenericClass(T value) {this.value value;}public T getValue() {return value;}
}
从泛型类派生的子类
// 从泛型类派生子类
class StringGenericClass extends GenericClassString {public StringGenericClass(String value) {super(value);}public void printValue() {System.out.println(Value: getValue());}
}调用子类方法
public class Main {public static void main(String[] args) {StringGenericClass stringInstance new StringGenericClass(Hello, Generics!);stringInstance.printValue(); // 输出: Value: Hello, Generics!}
}带多个类型参数的泛型类
// 定义一个带有多个类型参数的泛型类
class PairK, V {private K key;private V value;public Pair(K key, V value) {this.key key;this.value value;}public K getKey() {return key;}public V getValue() {return value;}
}// 从泛型类派生子类
class StringIntegerPair extends PairString, Integer {public StringIntegerPair(String key, Integer value) {super(key, value);}public void display() {System.out.println(Key: getKey() , Value: getValue());}
}// 使用示例
public class Main {public static void main(String[] args) {StringIntegerPair pair new StringIntegerPair(Age, 30);pair.display(); // 输出: Key: Age, Value: 30}
}
泛型接口
泛型接口语法
interface 接口名 泛型标识1...{泛型标识1 方法名(泛型标识1 变量名)}泛型接口的使用情况2种 实现类不是泛型 接口类型必须明确如果接口类型不明确值实现类按Object处理 实现类是泛型
实现类为泛型类 GenericInterface 是一个泛型接口GenericClass 是一个泛型类继承了这个接口。GenericClass 可以接受不同类型的参数。 // 定义一个泛型接口
interface GenericInterfaceT {void display(T value);
}// 实现泛型接口的泛型类
class GenericClassU implements GenericInterfaceU {Overridepublic void display(U value) {System.out.println(Value: value);}
}// 使用示例
public class Main {public static void main(String[] args) {GenericClassString stringInstance new GenericClass();stringInstance.display(Hello, Generics!); // 输出: Value: Hello, Generics!GenericClassInteger integerInstance new GenericClass();integerInstance.display(123); // 输出: Value: 123}
}
实现类为普通类 ConcreteClass 是一个普通类它实现了泛型接口 GenericInterface并将类型参数指定为 String。 // 定义一个泛型接口
interface GenericInterfaceT {void display(T value);
}// 实现泛型接口的普通类
class ConcreteClass implements GenericInterfaceString {Overridepublic void display(String value) {System.out.println(Value: value);}
}// 使用示例
public class Main {public static void main(String[] args) {ConcreteClass concreteInstance new ConcreteClass();concreteInstance.display(Hello, Generics!); // 输出: Value: Hello, Generics!}
}
泛型方法
简单的泛型方法
public class GenericMethodExample {// 定义一个泛型方法public T void printArray(T[] array) {for (T element : array) {System.out.println(element);}}public static void main(String[] args) {GenericMethodExample example new GenericMethodExample();// 使用泛型方法打印字符串数组String[] stringArray {Hello, Generics, !};example.printArray(stringArray); // 输出: Hello, Generics, !// 使用泛型方法打印整数数组Integer[] intArray {1, 2, 3, 4, 5};example.printArray(intArray); // 输出: 1, 2, 3, 4, 5}
}
带有多个类型参数的泛型方法
public class PairUtil {// 定义一个带有多个类型参数的泛型方法public static K, V void printPair(K key, V value) {System.out.println(Key: key , Value: value);}public static void main(String[] args) {// 使用泛型方法打印键值对printPair(Name, Alice); // 输出: Key: Name, Value: AliceprintPair(1, 100); // 输出: Key: 1, Value: 100}
}泛型方法是在调用方法的时候指明泛型的具体类型。重点看下泛型的方法图参考自https://www.cnblogs.com/iyangyuan/archive/2013/04/09/3011274.html
定义泛型方法语法格式 调用泛型方法语法格式 说明一下定义泛型方法时必须在返回值前边加一个T来声明这是一个泛型方法持有一个泛型T然后才可以用泛型T作为方法的返回值。
ClassT的作用就是指明泛型的具体类型而ClassT类型的变量c可以用来创建泛型类的对象。
Class 的基本概念
这里着重讲一下“Class” 的含义
Class 是一个表示某个类的对象T 是这个类的类型参数。每个类在 Java 中都有一个对应的 Class 对象这个对象包含了该类的结构信息如字段、方法、构造函数等。
如何获取 Class 对象
使用 ClassName.class
ClassString stringClass String.class;使用 getClass() 方法
String str Hello;
Class? stringClass str.getClass();使用 Class.forName()
try {Class? stringClass Class.forName(java.lang.String);
} catch (ClassNotFoundException e) {e.printStackTrace();
}以下示例展示了如何使用 Class 来获取类的信息
public class ClassExample {public static void main(String[] args) {// 获取 String 类的 Class 对象ClassString stringClass String.class;// 打印类的信息System.out.println(Class Name: stringClass.getName());System.out.println(Simple Name: stringClass.getSimpleName());System.out.println(Is Array: stringClass.isArray());System.out.println(Is Interface: stringClass.isInterface());System.out.println(Is Primitive: stringClass.isPrimitive());// 获取父类信息Class? superClass stringClass.getSuperclass();System.out.println(Superclass: superClass.getName());// 获取实现的接口Class?[] interfaces stringClass.getInterfaces();System.out.println(Interfaces:);for (Class? iface : interfaces) {System.out.println( - iface.getName());}}
}注意事项 Class 是 Java 反射机制中的一个重要组成部分能够让程序在运行时与类进行交互获取类的结构信息极大地增强了 Java 的灵活性和动态性。通过理解 Class开发者可以更有效地利用反射和泛型编程。 使用泛型来实现栈
泛型栈的定义
public class StackE {private E[] arr (E[]) new Object[10];//E[] arr new E[10];是不允许的private int flag 0;public void add(E x) {if(flag arr.length ) {E[] arrnew (E[]) new Object[arr.length * 2];for(int i 0;i arr.length;i) {arrnew[i] arr[i];}arr arrnew;}arr[flag] x;flag;}public E get() {if(flag0) {return null;}else {E x arr[flag--];return x;}}
}泛型栈的调用
public class Demo1 {public int x;public Demo1(int x) {this.x x;}Overridepublic String toString() {return Demo1 [x x ];}
}
public class Test {public static void main(String[] args) {StackDemo1 xx new Stack();for(int i 0;i 24;i) {xx.add(new Demo1(i));}for(int i 0;i 24;i) {System.out.println(xx.get());}}
}