减肥养生网站建设,开发公司宣传册,长沙高端网站制作公司,wordpress php版本太低一、泛型定义及作用
泛型是一种编程机制#xff0c;允许在编写代码时使用参数化类型#xff0c;以在编译时实现类型安全。 以下是泛型作用#xff1a; 增强代码可读性和可维护性#xff1a;通过在代码中使用泛型参数#xff0c;可以使代码更清晰、更具有可读性和可维护性…一、泛型定义及作用
泛型是一种编程机制允许在编写代码时使用参数化类型以在编译时实现类型安全。 以下是泛型作用 增强代码可读性和可维护性通过在代码中使用泛型参数可以使代码更清晰、更具有可读性和可维护性。 提高代码安全性泛型可以在编译时检查类型从而防止在运行时出现类型转换错误。 增加代码重用性泛型允许在不同的数据类型上编写通用代码从而提高代码的重用性。 简化代码使用泛型可以避免重复编写类似的代码从而简化代码。
总之泛型是一种强大的编程机制它可以帮助开发者编写更具可读性、可维护性、安全性和重用性的代码。
Java 泛型在编译期间会执行类型擦除Type Erasure。类型擦除是指编译器在编译泛型代码时会将泛型类型擦除为其原始类型或限定类型从而在运行时不存在泛型类型。在进行类型擦除时编译器会将泛型类型参数替换为它们的边界限定类型如果有的话如果没有指定限定类型则会将泛型类型参数替换为 Object 类型
例如一个泛型类定义如下
public class BoxT {private T content;public void setContent(T content) {this.content content;}public T getContent() {return content;}
}在编译后类型擦除会将泛型类型 T 擦除为 Object 类型生成的字节码如下
public class Box {private Object content;public void setContent(Object content) {this.content content;}public Object getContent() {return content;}
}需要注意的是尽管在运行时不存在泛型类型但是在编译期间编译器仍会对泛型类型进行类型检查从而确保类型安全。
二、泛型使用
1、泛型定义在类上
代码如下
class CommonUtil {public Object obj;public Object getObj() {return obj;}public void setObj(Object obj) {this.obj obj;}
}在使用的时候代码如下 public static void main(String[] args) {CommonUtil tool new CommonUtil();tool.setObj(2);Integer val1 (Integer)tool.getObj();tool.setObj(hello java);String val2 (String)tool.getObj();}从上述代码可以看出在获取值时每次都需要强转稍不留神就容易发生强转错误。所以能不能通过一种方式避免类型强转呢答案是泛型。将泛型定义在类上就可以避免类型转换。 改进代码如下
class CommonUtilT {public T obj;public T getObj() {return obj;}public void setObj(T obj) {this.obj obj;}
}在创建实例时把具体类型传入代码如下 public static void main(String[] args) {CommonUtilInteger tool new CommonUtil();tool.setObj(2);Integer val1 tool.getObj();CommonUtilString tool new CommonUtil();tool.setObj(hello java);String val2 tool.getObj();}2、泛型定义方法上
泛型定义在类上有个不太有好的一点看下面例子代码如下
class CommonUtilT {public void show(T obj){System.out.println(obj obj);}
}代码使用代码如下 CommonUtilInteger tool1 new CommonUtil();tool1.show(value);CommonUtilString tool2 new CommonUtil();tool2.show(111);CommonUtilPerson tool2 new CommonUtil();tool2.show(new Person());发现没每次调用 show() 方法都需要在通过创建实例因为在创建时可以指定具体使用的参数类型。但是这样创建对象太麻烦怎么解决可以将泛型定义在方法上代码如下
class CommonUtil {public W void show(W obj){System.out.println(obj obj);}
}使用代码如下 CommonUtil tool1 new CommonUtil();tool1.show(value);tool1.show(111);tool1.show(new Person());最后在方法调用时传入具体参数类型这样就可以避免重复创建对象做到一个方法重复调用和 Object 非常类似。包括 static 修饰的静态方法也是一样可以使用。代码如下
class CommonUtil {public static W void show(W obj){System.out.println(obj obj);}
}使用代码如下 CommonUtil.show(value);CommonUtil.show(111);CommonUtil.show(new Person());但是泛型定义在静态方法上还要注意这个静态方法不能使用类上面的泛型。为什么因为类是在创建时才会指定具体参数类型而静态方法是在类实例化之前就已经被加载到 JVM根本不知道你类在创建实例时传入的是什么具体参数类型。错误示例如下:
class CommonUtilW {public static W void show(W obj){System.out.println(obj obj);}
}3、泛型定义在接口上
有时候泛型会定义在接口上代码如下
public interface InterT {public void print(T obj);
}接口上的泛型那么可以在子类中指定、或不指定子类指定具体类型如下
public InterImpl implements InterString {// 接口上的方法public void print(String obj){}// 子类独有方法protect void show(Object obj){}
}在使用时代码如下 InterString inter new InterImpl();inter.print(hello);InterImpl impl new InterImpl();impl.show(new Object());或者子类中定义泛型接口定义具体类型代码如下
public InterImplW implements InterString {// 接口上的方法public void print(String obj){}// 子类独有方法protect void show(W obj){}
}在使用时代码如下 InterString inter new InterImpl();inter.print(hello);InterImplInteger impl new InterImpl();impl.show(new Integer(10));子类中也不知道具体类型那么也可以定义泛型把子类泛型传给接口代码如下
public InterImplW implements InterW {// 接口上的方法public void print(W obj){}// 子类独有方法protect void show(W obj){}
}在使用时代码如下 InterString inter new InterImpl();inter.print(hello);InterImplInteger impl new InterImpl();impl.show(new Integer(10));4、泛型通配符
举个例子代码如下
public class FanxinDemo {public static void print(CollectionString list) {list.forEach(e-{System.out.println(e e);});}public static void main(String[] args) {ListString list1 new ArrayList();list1.add(a);list1.add(b);list1.add(c);ListInteger list2 new ArrayList();list2.add(1);list2.add(2);print(list1);}
}可以发现 print() 方法只能输出参数类型是 String 的其他的参数都不能怎么可以做到公用这段代码这里介绍回个泛型通配符 ?当你不知道泛型是什么类型是就可以用这个暂时表示代码如下:
public class FanxinDemo {public static void print(Collection? list) {list.forEach(e-{System.out.println(e e);});}public static void main(String[] args) {ListString list1 new ArrayList();list1.add(a);list1.add(b);list1.add(c);ListInteger list2 new ArrayList();list2.add(1);list2.add(2);print(list1);print(list2);}
}但是假设现在不想让 print() 方法被 Integer 类型参数使用那么需要怎么做呢这就需要泛型限定了。
5、泛型限定
泛型限定可以限制参数类型范围? 这个级别范围太大不安全通过 extends、super 关键字来限定范围但是这两个关键字只能是单继承所以也是有局限的。限定分为两种让所有父类可以使用让所有的子类都可以使用
5.1、让所有父类可以使用
代码如下 public static void print(Collection? super Integer list) {list.forEach(e-{System.out.println(e e);});}表示让 Integer 所有父类都可以使用 print() 方法。
5.2、让所有子类可以使用
代码如下 public static void print(Collection? extends String list) {list.forEach(e-{System.out.println(e e);});}表示让所有的 String 子类可以使用 print() 方法。