java泛型常问面试题总结
Posted 流楚丶格念
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java泛型常问面试题总结相关的知识,希望对你有一定的参考价值。
文章目录
- Java泛型常问问题
- 1. Java中的泛型是什么 ? 使用泛型的好处是什么?
- 2. 如何编写一个泛型方法,让它能接受泛型参数并返回泛型类型?
- 3. 下面能编译通过?
- 4. Array中可以用泛型吗?
- 5. 编写Employee类
- 6. 你可以把`List`传递给一个接受`List`参数的方法吗?
- 7. java中List``和原始类型List之间的区别? 问的更具体一点就是java中Set和Set`<?>`到底区别在哪儿?
- 8. java中List`<?>`和 List``之间的区别是什么?
- 9. List``和原始类型List之间的区别?
- 10. java中的泛型是什么?使用泛型的好处是什么?
- 11. java的泛型是如何工作的?什么是类型擦除?
- 12. 什么是泛型中的限定通配符和非限定通配符?
- 13. java泛型的PESC原则。List`<? extends T>`和List`<? super T>`之间有什么区别?
- 14. 泛型类型变量不能是基本数据类型,只能是包装类型。
- 15. 运行时类型查询
- 16. 泛型在静态类和静态方法中的问题
- 17. 如何阻止java中的类型未检查的警告?
- 18. c++模板和java泛型之间有何不同?
Java泛型常问问题
1. Java中的泛型是什么 ? 使用泛型的好处是什么?
泛型是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。
泛型的本质是参数化类型,即给类型指定一个参数,然后在使用时再指定此参数具体的值,那样这个类型就可以在使用时决定了。这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
泛型的好处:
- 把运行时期的问题提前到了编译期间
- 避免了强制类型转换
2. 如何编写一个泛型方法,让它能接受泛型参数并返回泛型类型?
public <KKKK> KKKK function(KKKK k)
return k;
3. 下面能编译通过?
List<Object> objectList =null;
List<String> stringList =null;
objectList = stringList;
答:不能编译通过,泛型不支持协变,俩个泛型对象都不是一个类型
4. Array中可以用泛型吗?
不可以,集合可以,数组不行
5. 编写Employee类
(1)泛型类(两个泛型类型),定义name和age属性,类型是泛型类型,添加2个参数的构造方法、name和age属性的set和get方法,添加printInfo方法打印name和age值
(2)添加泛型方法printQ方法,参数为泛型
(3)定义泛型接口MyEmp,定义work和product方法(参数或者返回为泛型),Employee实现MyEmp接口
(4)测试Employee类,传入实际参数类型
代码如下:
package com.yyl;
interface MyEmp<M>
M work(M m);
void product(M m);
public class Employee<M,T,E> implements MyEmp<M>
private T name;
private E age;
public Employee(T name, E age)
this.name = name;
this.age = age;
public void printInfo()
System.out.println(this);
public <FAN> void printQ(FAN fan)
System.out.println(fan);
public T getName()
return name;
public void setName(T name)
this.name = name;
public E getAge()
return age;
public void setAge(E age)
this.age = age;
@Override
public String toString()
return "Employee" +
"name=" + name +
", age=" + age +
'';
@Override
public M work(M m)
return m;
@Override
public void product(M m)
System.out.println("嘎了");
public static void main(String[] args)
MyEmp<String> myEmp = new Employee<String,String,Integer>("李无衣",12);
myEmp.product("fafafa");
System.out.println(myEmp.work("hgagaga"));
Employee<String,String,Integer> employee = new Employee<>("扇轻罗",9999);
employee.printInfo();
employee.printQ("传一个泛型");
employee.printQ(46546546);
6. 你可以把List<String>
传递给一个接受List<Object>
参数的方法吗?
ArrayList<String> arrayList1 = new ArrayList<Object>();
ArrayList<Object> arrayList2 = new ArrayList,<String>();
很显然不能。例如以上写法是不正确的,虽然String继承自Object,但是ArrayList<String>
和ArrayList<Object>
是没有继承关系的。
并且泛型不支持协变
7. java中List<Object>
和原始类型List之间的区别? 问的更具体一点就是java中Set和Set<?>
到底区别在哪儿?
Set是不受类型检测机制检查的,而Set<?>
是受类型检测机制检查的。
例如下面代码:
public class SetDemo
public static void main(String[] args)
HashSet<Integer> s1 = new HashSet<>(Arrays.asList(1,2,3));
printSet(s1);
public static void printSet(Set s)
s.add(10); //这里不报错因为Set没有类型检查
for (Object o : s)
System.out.println(o);
public static void printSet1(Set<?> s)
s.add(10); //这里会报错,因为这里Set<?>会有类型检查
for (Object o : s)
System.out.println(o);
因为泛型会有类型检查
我们使用IDEA自动纠错的功能,他就会帮我们设置为Integer的泛型:
8. java中List<?>
和 List<Object>
之间的区别是什么?
- List
<?>
是一个未知类型的List - 而 List
<Object>
其实是任意类型的List
你可以把 List
<String>
、 List<Integer>
赋值给List<?>
,却不能把List<String>
赋值给 List<Object>
因为虽然String继承自Object,但是 List
<String>
和 List<Object>
没有关系。而 List
<String>
、 List<Integer>
都可以认为是 List<?>
的子类型。
9. List<String>
和原始类型List之间的区别?
List
<String>
受类型检测机制检查,而List不受类型检测机制检查。
10. java中的泛型是什么?使用泛型的好处是什么?
泛型是一种参数化类型的机制,使用泛型有以下两种好处:
- 类型检测提前到编译期,便于更早发现错误。
- 代码复用
- 避免了强制类型转换
例如下面代码体现了代码的可复用性:
public class SetDemo
public void sort(int [] a)
//这里只能添加int类型的数据
public <T> void sort1(T [] a)
//这里改为泛型类型,integer、Double等等类型都可以用了,提高了代码的复用性
注意:上面的integer类型不能改为Object,虽然可以添加,但是不能比较数据的大小。object类型的数据之间无法直接进行大小的比较,进行数据转化才可以。
11. java的泛型是如何工作的?什么是类型擦除?
java里面的泛型是一种伪泛型,只存在于java源码里面,在编译期时编译器会去检测泛型的类型,当我们把java代码编译成字节码后,泛型会退化,或者说是被擦除了。
java虚拟机不支持泛型,如果不擦除,虚拟机会认不出来。
12. 什么是泛型中的限定通配符和非限定通配符?
限定通配符有两种·:
? extends XXX // 上限
? super XXX // 下限
非限定通配符:
?
13. java泛型的PESC原则。List<? extends T>
和List<? super T>
之间有什么区别?
PE:List<? extends T>
,你可以把这个List当成是一个生产者,可以从里面拿东西但是不能从里面放东西。也就是PE 只读。
CS:List<? super T>
,可以把这个List当成一个消费者,你可以往里面存数据,但是不能往里面获取数据。也就是SC 只写。
14. 泛型类型变量不能是基本数据类型,只能是包装类型。
ArrayList<double> arr1 = new ArrayList`<>`(); 错误
ArrayList<Double> arr1 = new ArrayList`<>`(); 正确
15. 运行时类型查询
ArrayList<String> arr1 = new ArrayList<>();
if(arr1 instanceof ArrayList<String>) // 这是不行的,因为这里类型被擦除了*
if(arr1 instanceof ArrayList<?>) // 这里是可以的,因为ArrayList`<?>`就是一种未知类型*
16. 泛型在静态类和静态方法中的问题
public class Test<T>
// 这些都是错误的,因为你根本不知道这里的T是什么类型*
public static T one;
public static T show(T one)
return null;
// 这里是可以的,因为<>里面的T和上面的Test<>中的T没有任何关系*
public static <T> T show1(T one)
return null;
17. 如何阻止java中的类型未检查的警告?
这种警告可以使用@SuppressWarnings(“unchecked”)
注解来屏蔽。
18. c++模板和java泛型之间有何不同?
c++里面是真正的泛型,而java里面是伪泛型
在c++中,模板本质上就是一套宏指令集,只是换了个名头,编译器会针对每种类型创建一份模板代码的副本,由于架构上的差异,java泛型和c++模板有很多不同点:
c++可以使用int等基本数据类型,java则不行,必须转而使用Integer;
在java中可以将模板的参数类型限定为某种特定类型;
在c++中,类型参数可以实例化,而java不支持。
以上是关于java泛型常问面试题总结的主要内容,如果未能解决你的问题,请参考以下文章