天津建设网站首页,软件工程考研方向有哪些,现在流行的网站开发,企业推广网站的方法目录一、基本介绍1、Java泛型的基本语法格式为#xff1a;2、在使用泛型时#xff0c;还需要注意以下几点#xff1a;二、泛型的优点1、类型安全2、消除强制类型转换3、更高的效率4、潜在的性能收益三、常见泛型字母含义四、使用泛型时的注意事项五、泛型的使用1、泛型类2、…
目录一、基本介绍1、Java泛型的基本语法格式为2、在使用泛型时还需要注意以下几点二、泛型的优点1、类型安全2、消除强制类型转换3、更高的效率4、潜在的性能收益三、常见泛型字母含义四、使用泛型时的注意事项五、泛型的使用1、泛型类2、泛型接口3、泛型通配符4、泛型方法六、Java泛型上下边界1、上边界2、下边界七、泛型擦除大家好我是哪吒。
一、基本介绍
Java泛型Generics是一种强类型约束机制用于在编译时检查代码的类型安全性。它可以让程序员定义一些具有通用性的类、接口和方法以便在后续使用中可以适用于不同的数据类型。
1、Java泛型的基本语法格式为
public class StudentT {private T value;public void setValue(T value) {this.value value;}public T getValue() {return value;}
}在上面的示例代码中我们定义了一个泛型类MyClass其中T表示类型参数Type Parameter。在类的成员变量和方法中我们都可以使用T来代替实际的数据类型从而实现对不同数据类型的支持。
通过使用泛型可以大大提高代码的可读性和类型安全性并且避免了需要进行强制类型转换的繁琐操作。同时泛型还可以提高代码的重复利用率减少代码量提高开发效率。
2、在使用泛型时还需要注意以下几点
泛型只能使用引用类型不能使用基本类型;不能创建泛型数组但可以使用泛型集合Java的泛型是通过类型擦除type erasure实现的在编译期间会被转换为原始类型因此无法在运行时获取泛型类型的具体信息Java中的泛型不支持协变和逆变但Java SE 8及以上版本引入了一些新特性来支持函数式编程中的协变和逆变。
二、泛型的优点
1、类型安全
泛型的主要目的是提高Java程序的类型安全。通过知道使用泛型定义的变量的类型限制编译器可以在非常高的层次上验证类型假设。没有泛型这些假设就只能存在于系统开发人员的头脑中。
通过在变量声明中捕获这一附加的类型信息泛型允许编译器实施这些附加的类型约束。类型错误就可以在编译时被捕获了而不是在运行时当作ClassCastException展示出来。将类型检查从运行时挪到编译时有助于Java开发人员更早、更容易地找到错误并可提高程序的可靠性。
2、消除强制类型转换
泛型的一个附带好处是消除源代码中的许多强制类型转换。这使得代码更加可读并且减少了出错机会。尽管减少强制类型转换可以提高使用泛型类的代码的累赞程度但是声明泛型变量时却会带来相应的累赞程度。在简单的程序中使用一次泛型变量不会降低代码累赞程度。但是对于多次使用泛型变量的大型程序来说则可以累积起来降低累赞程度。所以泛型消除了强制类型转换之后会使得代码加清晰和筒洁。
3、更高的效率
在非泛型编程中将筒单类型作为Object传递时会引起Boxing装箱和Unboxing拆箱操作这两个过程都是具有很大开销的。引入泛型后就不必进行Boxing和Unboxing操作了所以运行效率相对较高特别在对集合操作非常频繁的系统中这个特点带来的性能提升更加明显。
4、潜在的性能收益
泛型为较大的优化带来可能。在泛型的初始实现中编译器将强制类型转换没有泛型的话Java系统开发人员会指定这些强制类型转换插入生成的字节码中。但是更多类型信息可用于编译器这一事实为未来版本的JVM的优化带来可能。
三、常见泛型字母含义
格式 类名字母列表
T Type表示类型K V 分辨表示键值对中的key valueE 代表Element?表示不确定的类型
四、使用泛型时的注意事项
1、在定义一个泛型类时在“”之间定义形式类型参数例如“class TestGenK,V”其中“K”“V”不代表值而是表示类型。
2、实例化泛型对象时一定要在类名后面指定类型参数的值类型一共要有两次书写。
3、使用泛型时泛型类型必须为引用数据类型不能为基本数据类型Java中的普通方法构造方法静态方法中都可以使用泛型方法使用泛型之前必须先对泛型进行声明可以使用任意字母一般都要大写。
4、不可以定义泛型数组。
5、在static方法中不可以使用泛型泛型变量也不可以用static关键字来修饰。
6、根据同一个泛型类衍生出来的多个类之间没有任何关系不可以互相赋值。
7、泛型只在编译器有效
五、泛型的使用
泛型有三种使用方式分别为泛型类、泛型接口、泛型方法
1、泛型类
//此处T可以随便写为任意标识常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时必须指定T的具体类型
public class StudentT {//key这个成员变量的类型为T,T的类型由外部指定private T key;//泛型构造方法形参key的类型也为TT的类型由外部指定public Student(T key){this.key key;}//泛型方法getKey的返回值类型为TT的类型由外部指定public T getKey(){return key;}public static void main(String[] args) {//泛型的类型参数只能是类类型包括自定义类不能是简单类型//传入的实参类型需与泛型的类型参数类型相同即为Integer.StudentInteger student new StudentInteger(123456);//传入的实参类型需与泛型的类型参数类型相同即为String.StudentString str new StudentString(哪吒编程);System.out.println(泛型测试key is student .getKey());System.out.println(泛型测试key is str.getKey());}
}泛型参数就是随便传的意思
Student student1 new Student(哪吒编程);
Student student2 new Student(4444);
Student gstudent3 new Student(55.55);
Student student4 new Student(false);2、泛型接口
泛型接口与泛型类的定义及使用基本相同。泛型接口常被用在各种类的生产器中可以看一个例子
//定义一个泛型接口
public interface GeneratorT {public T next();
}当实现泛型接口的类未传入泛型实参时
/*** 未传入泛型实参时与泛型类的定义相同在声明类的时候需将泛型的声明也一起加到类中* 即class FruitGeneratorT implements GeneratorT{* 如果不声明泛型如class FruitGenerator implements GeneratorT编译器会报错Unknown class*/
class FruitGeneratorT implements GeneratorT{Overridepublic T next() {return null;}
}当实现泛型接口的类传入泛型实参时
package javase.genericity;import java.util.Random;public class FruitGenerator implements GeneratorString{String[] fruits new String[]{apple,banana,Pear};Overridepublic String next() {Random random new Random();System.out.println(fruits[random.nextInt(3)]);return fruits[random.nextInt(3)];}public static void main(String[] args) {FruitGenerator ff new FruitGenerator();ff.next();}
}3、泛型通配符
Java泛型通配符wildcard用于表示某个类型参数可以接受任意类型的实参采用“?”作为通配符。
在使用泛型时有时候需要定义一个方法或类能够接受多种类型的参数。这时就可以使用泛型通配符来实现。Java中有三种泛型通配符extends、super和无限制通配符。
1extends通配符
表示该类型参数是某个特定类型的子类或本身可以接受该类型及其子类的实参。
例如
public void printList(List? extends Number list) {for (Number n : list) {System.out.println(n);}
}2super通配符
表示该类型参数是某个特定类型的超类或本身可以接受该类型及其父类的实参。
例如
public void addList(List? super Integer list) {list.add(1);list.add(2);list.add(3);
}3无限制通配符
表示该类型参数可以接受任意类型的实参。
例如
public void showList(List? list) {for (Object o : list) {System.out.println(o);}
}泛型通配符只能用于方法参数、返回值和局部变量等地方不能用于类的定义中。同时在使用泛型通配符时应该遵循PECS原则Producer Extends, Consumer Super即生产者使用extends通配符消费者使用super通配符以保证类型安全。
4、泛型方法
Java中的泛型方法是指在方法名称前加上的方法它可以接受任意类型的参数。
下面是一个简单的示例
public class GenericExample { public T T[] createArray(T[] array) { return array; }
}在上面的示例中createArray方法接受一个T[]类型的参数并返回一个T[]类型的数组。在方法体中我们可以使用array参数来创建一个T[]类型的数组。
需要注意的是泛型方法的参数类型必须与方法体中的参数类型相同。如果方法体中的参数类型与方法名称前加上的参数类型不同则编译器会报错。
六、Java泛型上下边界
Java泛型上下边界是指在定义泛型时我们可以通过指定类型参数的上限或下限来限制实际参数的类型范围。
1、上边界
使用extends关键字来限制类型参数的上限表示该类型参数必须是指定类型的子类或本身。
public class MyClassT extends Number {// 类定义
}在上面的示例中我们使用extends关键字将类型参数T的上限指定为Number类表示只有Number及其子类才能作为实参传递进来。
2、下边界
使用super关键字来限制类型参数的下限表示该类型参数必须是指定类型的超类或本身。
public class MyClassT super Integer {// 类定义
}在上面的示例中我们使用super关键字将类型参数T的下限指定为Integer类表示只有Integer及其父类才能作为实参传递进来。
需要注意的是在使用上下边界时如果同时指定了上下边界则应该先指定下边界再指定上边界。同时在使用上下边界时也需要遵循PECS原则Producer Extends, Consumer Super即生产者使用extends通配符消费者使用super通配符以保证类型安全。
七、泛型擦除
Java泛型擦除是指在Java编译器将泛型类型的代码编译成字节码时会将所有泛型类型的信息删除以避免运行时带来的额外开销。
在Java中泛型只是一种编译时检查机制并不会影响程序的运行时行为。在编译期间Java编译器会将泛型类型擦除为原始类型并在必要时插入强制类型转换语句。
ListString list new ArrayList();
list.add(哪吒编程);
String s list.get(0);然我们使用了泛型类型List但在编译后它会被擦除为List因此get()方法返回的实际类型为Object并且需要进行强制类型转换才能得到String类型的值。
由于泛型擦除的存在导致在运行时无法获取泛型类型的具体信息因此在使用反射和类型转换等相关操作时需要格外小心以避免产生类型安全问题。
需要注意的是在Java SE 8及以上版本中引入了新的特性来支持对函数式接口中的泛型类型进行推断和获取以及在局部变量初始化时使用类型推断从而进一步提高了泛型的灵活性和可读性。 本文收录于Java基础教程系列。
目前已经700订阅CSDN最强Java专栏包含全部Java基础知识点、Java8新特性、Java集合、Java多线程、Java代码实例理论结合实战实现Java的轻松学习。
哪吒多年工作总结Java学习路线总结搬砖工逆袭Java架构师。