精华内容
下载资源
问答
  • 微信公众号:大黄奔跑 关注我,可了解更多有趣的面试相关问题。 文章目录写在之前面试问题概览真实面试回顾总结番外 ...下面我罗列一些大厂面试中,对于泛型一些常见问题泛型了解吗?介绍一下泛型?【快手】 .

    微信公众号:大黄奔跑
    关注我,可了解更多有趣的面试相关问题。

    写在之前

    本文主要向面试角度讲述一个问题在面试中该如何回答,如果只想看问题答案,可以重点留意灰色背景的问题,其他的文字主要是扩展内容。

    关于泛型,Jdk1.5以后推出来的特性,已经推出被Java程序员热捧,因为其实实在在解决一些编码问题。下面我们来看看如此重要的泛型,在面试中会怎么考察呢。

    面试问题概览

    下面我罗列一些大厂面试中,对于泛型一些常见问题。

    1. 泛型了解吗?介绍一下泛型?【快手】
    2. 泛型实现的原理,为什么要实现泛型【阿里】
    3. 泛型实现原理 【去哪儿】
    4. java的泛型,superextend的区别?泛型擦除的原理【华为】
    5. 什么是泛型,什么时候需要利用泛型【字节跳动】
    6. java的泛型,有什么缺点【腾讯】

    可以看到泛型在各个大厂面试中已经成为了笔考题目,回想自己当初校招,因为泛型回答不好而错失阿里Offer,至今仍然悔恨不已。

    真实面试回顾

    一个身着灰色格子衬衫,拿着闪着硕大的🍎logo小哥迎面走来,我心想,logo还自带发光的,这尼玛肯定是p7大佬了,但是刚开始咱们还是得淡定不是。

    大黄同学是吧,我看你简历上面写熟悉Java基础以及常见的Java特性。那你先说说你对泛型的理解吧

    此刻咱们得淡定,虽然自己准备过,也得慢慢道来。

    面试官您好,泛型是JDK1.5之后提出的新概念,本意是让同一套代码可以适应更多的类型。

    大家都写过议论文对吧,对于一个问题需要正反两面说,优点、缺点,一一道来。

    缺点:在没有泛型之前一旦某个接口定义了参数为某个类型,则实现了该接口的方法必须采用同样类型参数,不利于程序的扩展。
    优点:

    1. 比如在创建容器的时候,指定容器持有何种类型,以便在编译期间就能够保证类型的正确性,而不是将错误留到运行的时候
    2. 无论是创建类、方法的时候都可以泛化参数,可以做到代码的复用。
      泛型的出现最主要目的为了更好的创建容器类

    比如下面这个例子中,在定义Dog类的时候不需要指定其属性a的含义,只需要利用T来表示,在new该对象的时候指定对应的类型即可。

    /**
     * 
     * @param <T>
     */
    public class Dog<T> {
        private T a;
        public Dog(T a) {
            this.a = a;
        }
    
        public void set(T a) {
            this.a = a;
        }
        public T get() {
            return a;
        }
    
        public static void main(String[] args) {
            // 在实例化的时候才确定类型
            Dog<Integer> h3 = new Dog<Integer>(new Integer(3));
            // 然后就可以不用强制类型转化了
            Integer a = h3.get();
            // h3.set("Not an Automobile"); // Error
            // h3.set(1.11); // Error
        }
    } 
    

    面试官摸了摸笔记本,心想,回答的还可以,继续追问。

    你刚才说泛型消除了类型之间的差异,那你知道jdk底层是如何做到的吗?

    大黄:

    jdk是通过类型擦除来实现泛型的,编译器在编译之后会擦除了所有类型相关的信息,所以在运行时不存在任何类型相关的信息。比如如果编写 List<String> names = new Arraylist<>();在运行的时候,仅用List来表示。

    先不要高兴,面试官可能会继续追问。

    面试官:既然你说编译时就已经擦除了,为什么要用类型擦除呢?
    大黄:这么做是为了向前兼容,为了兼容jdk1.5以前的程序,确保能和Java 5之前的版本开发二进制类库进行兼容。

    好小伙,这都知道,看来之前做足了功课,还得继续问问,试试深浅。

    面试官:你知道泛型中的通配符吧,那你说一下什么是限定通配符和非限定通配符。
    大黄:限定通配符,是限定类型必须是某一个类型的子类。
    比如:List<? extends Fruit> flist表示具有任何从Fruit继承的类型的列表。
    而限定通配符:<? super Fruit> 确保类型必须是Fruit的父类来设定类型的下界。

    大黄小提醒

    不要意味new一个List<? extends Fruit>flist就可以把任何的水果塞到flist里面,很遗憾的告诉你,下面的程序编译不通过的。

    /**
     * 泛型中通配符的应用
     */
    public class GenericsAndCovariance {
        public static void main(String[] args) {
            // new一个水果篮子
            List<? extends Fruit> flist = new ArrayList<Apple>();
            // 下面编译不会通过
            flist.add(new Apple());
            // 下面编译不会通过
            flist.add(new Orange());
            // 下面编译同样不会通过
            // flist.add(new Fruit());
        }
    }
    

    看到这个程序是否感觉到有点懵,我自己创建的水果篮子,我无法往里面放苹果、橙子,甚至连篮子对象也不能放。那我这个篮子还有屁用哦。
    是的,确实没有什么用,似乎和预期不太一样。
    但是想想也合乎道理。如果不知道list持有什么对象,那么怎么样才能安全地向其中添加对象呢?如果允许了,则获取元素的时候,就会出错。

    下面面试继续:

    面试官:那你再说说泛型可以用到什么地方?
    大黄:泛型即可用用于类定义中、接口的定义、方法的定义、同时也广泛用于容器中。

    1. 在类中使用泛型,可以让类中的属性由泛型定义,而不需要提前知道属性的类型。
    2. 在接口中使用泛型,可以让接口方法的返回值按照各自实现自由定义。这也是常见的工厂设计模式的一种应用。
    3. 在方法中利用泛型,可以做到方法的复用,同一个方法可以传入不同类型参数。实现时只需要将泛型参数列表置于返回值之前即可,JDK1.8中Stream中很多流式方法的定义采用了泛型。

    记得加上这句话

    我觉得,使用泛型机制最吸引人的地方,在使用容器的地方,比如List、Set、Map,因为在1.5以前,在泛型出现之前,当将一个对象放到容器中,这个对象会默认的转化为Object类型,因此会丢失掉类型信息,可能将一个Apple对象放到Orange容器中,然后试图从Orange容器中获取对象时,得到的是一个Apple,强制转化必然出问题,会抛出RuntimeException,但是有了泛型之后,这种问题在写代码,也就是说在编译期间就会暴露,而不是在运行时暴露。

    比如下面定义接口用于生成不同的对象:

    /**
     * 定义一个生成器
     * @param <T>
     */
    public interface Generator<T> {
        /**
         * 定义生成下一个对象
         * @return
         */
        T next();
    }
    
    /**
     * 利用泛型生成器来生成费波列切数
     */
    public class Fibonacci implements Generator<Integer> {
        private int count = 0;
    
        public static void main(String[] args) {
            Fibonacci gen = new Fibonacci();
            for (int i = 0; i < 18; i++)
                System.out.print(gen.next() + " ");
        }
        /**
         * 实现接口的方法,返回值为Integer
         * @return
         */
        public Integer next() {
            return fib(count++);
        }
        /**
         * 定义费波列切数
         * @param n
         * @return
         */
        private int fib(int n) {
            if (n < 2) return 1;
            return fib(n - 2) + fib(n - 1);
        }
    }
    

    泛型方法的应用:

    public class GenericMethods {
    
        public static void main(String[] args) {
            GenericMethods gm = new GenericMethods();
            gm.f("");
            gm.f(1);
            gm.f(gm);
        }
    
        /**
         * 定义泛型方法
         * @param x         方法的参数为泛型
         * @param <T>
         */
        public <T> void f(T x) {
            System.out.println(x.getClass().getName());
        }
    }
    

    回答到这里,关于泛型的问题基本上总结的差不多了。

    总结

    本身主要围绕开头的几个真正的面试题展开,简单来说,泛型是什么?为什么要有泛型?泛型如何实现的?泛型有哪些用处。
    个人观点,一个技术从刚开始学习的时候,从四方面思考,能够事半功倍。

    最后大黄分享多年面试心得。面试中,面对一个问题,大概按照总分的逻辑回答即可。先直接抛出结论,然后举例论证自己的结论。一定要第一时间抓住面试官的心里,否则容易给人抓不着重点或者不着边际的印象。

    番外

    另外,关注大黄奔跑公众号,第一时间收获独家整理的面试实战记录及面试知识点总结。

    我是大黄,一个只会写HelloWorld的程序员,咱们下期见。

    关注大黄,充当offer收割机

    展开全文
  • 1、 泛型从JDK1.5之后追加到Java语言里面的,其主要目的是为了解决ClassCastException的问题,在进行对象的向下转型时,永远都存在有安全隐患。可以编译,运行错误 解决大多部分 2、而泛型的本质在于,类中的属性或...

    一、由来

    1、 泛型从JDK1.5之后追加到Java语言里面的,其主要目的是为了解决ClassCastException的问题,在进行对象的向下转型时,永远都存在有安全隐患。可以编译,运行错误 解决大多部分

    2、而泛型的本质在于,类中的属性或方法的参数与返回值可以由对象实例化的时候动态决定。
    在这里插入图片描述
    回避掉对象的强制转换
    在这里插入图片描述

    二、基础

    1、Point 这个T表示派生自Object类的任何类 一般大写字母

    优点 1、Object 要强制转换 泛型不用 2、传入类型不对,编译时会报错

    常用元素表示:
    class MorePoint<T,U,A,B,C>{ }

    • E — Element,常用在java Collection里,如:List,Iterator,Set
    • K,V — Key,Value,代表Map的键值对
    • N — Number,数字
    • T — Type,类型,如String,Integer等等

    2、?与 T
    T的作用是限制泛型可用类型,泛型类的类型必须实现或继承了anyClass这个接口或类,无论anyClass是接口还是类.

    ?是类型通配符,其主要作用是创建一个泛型类对象时限制这个泛型类的类型实现或继承继承某个接口或类的子类.

    ·?extends 类:设置泛型上限;|-例如:"? extends Number":表示该泛型类型只允许设置Number或者Number的子类

    ·? super 类: 设置泛型的下限: |-例如:"? super String":只能够使用String或其父类。
    3、其他问题

    interface IPoint<S>{
          public String print(S s) ;
    }
    class PointImpl implements IPoint<T> // 错误   T 不能单独出现在接口中
    class PointImpl implements IPoint<String> //正确
    class PointImpl<T> implements IPoint<T>  //子类中接口方法与IPoint<T> T类型一致
    class InfoImpl<T,K,U> implements Info<U> //泛型类
    public static <T>list<T> aslist(T...a)  //<T> 表示泛型方法 T 表示泛型类型
    public static  <T> void StaticMethod(T a)
     //
    public class StaticFans {  
        //静态函数  
        public static  <T> void StaticMethod(T a){  
            Log.d("harvic","StaticMethod: "+a.toString());  
        }  
        //普通函数  
        public  <T> void OtherMethod(T a){  
            Log.d("harvic","OtherMethod: "+a.toString());  
        }  
    }  
    //静态方法  
    StaticFans.StaticMethod("adfdsa");//使用方法一  必须是派生自Object类的类型 隐式
    StaticFans.<String>StaticMethod("adfdsa");//使用方法二  
      
    //常规方法  
    StaticFans staticFans = new StaticFans();  
    staticFans.OtherMethod(new Integer(123));//使用方法一  
    staticFans.<Integer>OtherMethod(new Integer(123));//使用方法二
    

    4、 <T> T 与Class <?> clazz
    < T > 表示传入的类型 T表示返回类型(比如String、int)
    Class 传递类的class对象,传入类型 (T aa)
    关于的进一步说明(参考自
    按理说有一个T表示返回值就可以了,为什么还要一个呢?这个表示这个方法声明为泛型方法.

    但是又有一种情况出现了,同样是泛型方法,为什么下面的getName方法就不用声明呢?

    public class Test1<T> {
        private T name;
        public T getName(T name){
            return name;
        }
        public static <T> void printA(T a){
            System.out.println(a);
        }
     
    }
    

    解释:对于声明了的类(Test1就是声明了的类)不需要声明泛型方法,对于带了static的方法,它并不属于类的一部分,所以相当于没有声明的类,所以需要声明为泛型方法.
    像Test2这样的类就必须声明泛型方法

    public class Test2 {
        public <T> T test1(T A){
            System.out.println(A);
            System.out.println(A.getClass());
            return A;
        }
    }
    

    三、泛型擦除

    过程:检查代码中泛型的类型(引用),然后再进行类型擦除,在进行编译的。

    运行时可以设置任意类型,不受类型限制,例如:
    在这里插入图片描述
    打印:
    在这里插入图片描述

    因为类型擦除的问题,所以所有的泛型类型变量最后都会被替换为原始类型。这样就引起了一个问题,既然都被替换为原始类型,那么为什么我们在获取的时候,不需要进行强制类型转换呢?
    自动类型转换
    看下ArrayList和get方法:

    1. public E get(int index) {
         RangeCheck(index); 
         return (E) elementData[index];
         } 
      

    看以看到,在return之前,会根据泛型变量进行强转。

    编译时泛型擦除 原始类型 最小父类型 知道Object

    泛型类中的静态方法和静态变量不可以使用泛型类所声明的泛型类型参数

    所以,虚拟机巧妙的使用了桥方法,来解决了类型擦除和多态的冲突。

    泛型的类型参数不能用在Java异常处理的catch语句中。 分不清异常

    原始类型List和带参数类型List<Object>之间的主要区别是,在编译时编译器不会对原始类型进行类型安全检查,却会对带参数的类型进行检查。

    展开全文
  • java 泛型问题

    2021-03-09 20:42:57
    问题需要对泛型有深刻了解,原理题主明白,只是不明白我下面说明的这个问题代码如下public class Shape implements Comparable {@Overridepublic int compareTo(Shape o) {return 0;}}public class Square extends...

    本问题需要对泛型有深刻了解,原理题主明白,只是不明白我下面说明的这个问题

    代码如下

    public class Shape implements Comparable {

    @Override

    public int compareTo(Shape o) {

    return 0;

    }

    }

    public class Square extends Shape {

    }

    public class TestGenetic {

    public static > AnyType findMax(AnyType[] arr){

    int maxIndex=0;

    for (int i = 0; i

    if (arr[i].compareTo(arr[maxIndex+1])>0)

    maxIndex=i;

    }

    return arr[maxIndex];

    }

    public static void main(String[] args) {

    Shape[] shapes={new Shape(),new Shape()};

    Square[] squares={new Square(),new Square()};

    findMax(shapes);

    findMax(squares);

    }

    }

    若修改一下泛型泛型方法中的泛型:

    public class TestGenetic {

    public static > AnyType findMax(AnyType[] arr){

    int maxIndex=0;

    for (int i = 0; i

    if (arr[i].compareTo(arr[maxIndex+1])>0)

    maxIndex=i;

    }

    return arr[maxIndex];

    }

    public static void main(String[] args) {

    Shape[] shapes={new Shape(),new Shape()};

    Square[] squares={new Square(),new Square()};

    findMax(shapes);

    findMax(squares);

    }

    }

    同样不会报错

    但是,在泛型类中则不是这样

    public class TestGeneric1> {

    public static void main(String[] args) {

    TestGeneric1 p=null;

    }

    }

    这种不会报错,但是,如果我修改一下泛型,如下:

    public class TestGeneric1> {

    public static void main(String[] args) {

    TestGeneric1 p=null;//编译报错

    }

    }

    则编译报错,请问为什么在泛型类中会进行泛型检查,而泛型方法中不进行检查呢,在泛型方法中,Square明明不符合AnyType extends Comparable这一条件呀

    请指教,谢谢

    展开全文
  • 在我的游戏引擎中,我有一个实体对象列表,其中有许多子类(例如播放器,立方体,相机等).我想有一个方法,我传递一个Class对象,最后得到一个相同类的List – 例如我想说这样的话:List boxes = getEntities(Box.class);...

    在我的游戏引擎中,我有一个实体对象列表,其中有许多子类(例如播放器,立方体,相机等).我想有一个方法,我传递一个Class对象,最后得到一个相同类的List – 例如我想说这样的话:

    List boxes = getEntities(Box.class);

    到目前为止我有这个:

    public List getEntities(Class extends Entity> t) {

    ArrayList list = new ArrayList<>();

    for (Entity e : entities) {

    if (e.getClass() == t) {

    list.add(e);

    }

    }

    return Collections.unmodifiableList(list);

    }

    但是当然返回实体列表,这意味着列表中的每个实例都必须转换为Box类.有没有办法在Java中正确地做到这一点?

    最佳答案 我推荐以下内容,它建立在现有答案的基础上,但避免使用@SuppressWarnings等:

    public List getEntities(Class type) {

    List list = new ArrayList<>();

    for (Entity e : entities) {

    if (type.isInstance(e)) {

    list.add(type.cast(e));

    }

    }

    return Collections.unmodifiableList(list);

    }

    或者,如果您使用的是Guava:

    public ImmutableList getEntities(Class type) {

    return ImmutableList.copyOf(Iterables.filter(entities, type));

    }

    展开全文
  • 关于Java中的泛型问题

    2021-01-28 14:04:17
    关于Java中的泛型问题 发生背景 mybatis的xml中定义的resultType=“map” dao接口中定义的返回值为List 运行期间并没有报错,debug发现返回值中存的类型为List<Map<String, Object>> 产生问题 编译...
  • 关于Java泛型的面试题

    2021-02-12 21:06:38
    Java中的泛型是什么 使用泛型的好处是什么这是在各种Java泛型面试中,一开场你就会被问到的问题中的一个,主要集中在初级和中级面试中。那些拥有Java1.4或更早版本的开发背景的人 都知道,在集合中存储对象并在使用...
  • Java泛型问题:类“不在类型变量的范围内”错误。(Java generics issue: Class “not within bounds of type-variable” error.)我正在开发一个涉及泛型的类的项目。public interface Keyable {public String getKey...
  • 简介上一篇文章介绍了泛型的基本用法以及类型擦除的问题,现在来看看泛型和数组的关系。数组相比于Java 类库中的容器类是比较特殊的,主要体现在三个方面:数组创建后大小便固定,但效率更高数组能追踪它内部保存的...
  • java 泛型编程(一)

    2021-03-11 13:23:32
    Technorati 标记: java,泛型,genericjava泛型应用是java核心基础之一,从java 5开始引进泛型。如果你曾经使用过java Collection,那你已经算是接触过泛型了。在java Collection里使用泛型是一件很简单的事情,可泛型...
  • 这个问题部分与我上次的question有关.我有一个表示泛型对象集合的泛型类:public interface MyObject{}public interface MyCollecion {public foo(MyObject obj)}在我的设计中,这些对象集合由客户端类(我们称之为...
  • mybatis查询结果集有泛型属性时可能出现的问题问题:当接收结果为map或者对象的属性为泛型时: @Data public class GenericKeyValueVo<K,V> { private K key; private V value; } 这时候如果直接将...
  • #先上代码/*** 解析泛型类型* @param type* @return*/public static List> parseGenericType(Type type){List> rootList = new ArrayList>();if(type instanceof ParameterizedType){ParameterizedType ...
  • 难点是泛型如何转换一、arrayList>转化json字符串,存入redis缓存ArrayList> listProfit//将ArrayList>类型数据转换成json字符串String listProfitPctJsonStr = JSON.toJSONString(listProfit);//然后将...
  • Java语言的泛型采用的是擦除法实现的伪泛型泛型信息(类型变量、参数化类型)编译之后通通被除掉了。使用擦除法的好处就是实现简单、非常容易Backport,运行期也能够节省一些类型所占的内存空间。而擦除法的坏处...
  • Java泛型面试问题

    2021-03-14 12:13:16
    Java面试中的通用面试问题在相当长的时间内在Java 5周围越来越普遍,许多应用程序都转移到Java 5上,并且几乎所有新的Java开发都发生在Tiger(Java 5的代号)上。泛型和Java 5功能(例如Enum)的重要性,Collection实用...
  • Java泛型与Kotlin泛型

    2021-04-08 12:14:52
    本文主要列举Java泛型与Kotlin泛型的基本知识,以及两者的区别。 什么泛型 泛型程序设计是程序设计的一种风格或或规范。简单的说就是该类型可变,在编写代码时可以根据情况设置不同的类型。因为泛型的可变性,很容易...
  • 其实这个问题的答案我之前也看到过,不过没有联想起来;具体就是Java的泛型机制就是擦除机制;下面的文章做了想起的解释帐号登录​blog.csdn.netC++泛型C++泛型跟虚函数的运行时多态机制不同,泛型支持的静态多态,...
  • 泛型

    2021-01-07 20:57:58
    泛型类型1,泛型类型2,…泛型类型n> 泛型类型:必须是引用类型,如果需要基本数据类型作为泛型,请使用包装类。 3、代码示例 import java.util.ArrayList; import java.util.List; public class Demo6_泛型 { ...
  • 函数式编程最开始的版本忘记了接口的情况…publicclassEEE{publicstaticvoidmain(String[]args){Listtypes=newArrayList();findAllTypes(DDD.class,types);System.out.println(types);}...
  • 泛型就是解决: 类, 接口, 方法的复用, 以及对不特定数据类型的支持(类型检测 类型约束) 泛型方法 类型检测 main() { print(getData1(bool)); //无类型检测 print(getData1<String>('value')); //类型...
  • 从JDK1.5以后引入了三大常用新特性:泛型、...一、泛型问题的引出假设需要你定义一个描述坐标的程序类Point,需要提供两个属性x、y。对于这两个属性的内容可能有如下选择:1. x = 10、y = 20 ;2. x = 10.1、y = ...
  • 它需要一个非泛型版本的java.util.Enumeration:public void someMethod(java.util.Enumeration e) {...}我试过下面的代码来调用这个方法:target.someMethod(new java.util.Enumeration[String] {def hasMoreElemen...
  • 背景为什么JDK5要引入泛型泛型保证参数类型一致性。什么叫类型一致?假设有继承关系,A ArrayList list;list.add(new C());list.add(new D());list.add(new B());//compile ERROR并没有破坏list的类型一致性,因为...
  • 一、Dart 泛型类与泛型方法、 二、Dart 泛型中的特定类型约束、 三、Dart 自带泛型、 四、完整代码示例、 五、 相关资源、
  • 在 Java 1.5 之前没有泛型,通常需要使用强制类型转换的方式将一种数据类型转换为另一种数据类型,这种转换要求开发者对实际参数的类型具有可预知性。对于强制类型转换错误的情况,编译器可能不会提示错误,但是在...
  • 请说一下泛型的作用,泛型类和泛型方法有什么区别? 2. 题目剖析 关于泛型,对于初学Java的学生来说,其实并不是很容易理解,刚开始的时候,可能拿不准这个泛型到底是干嘛的。但是开发时,泛型用的还是很多的,...
  • 如果其他28个左右的类也提供了这些类(如您的问题所暗示),则只需为所有类实现具有这些方法的通用接口即可.然后,您可以将方法的通用类型绑定到该接口,并放弃所有instanceof语句和后续的显式转换.唯一的缺点是,如果列表...
  • 如下的程序,介绍泛型方法的,有个疑问:fromArrayToCollection方法有两个T类型形参,名为a的T类型数组和一个T类型对象组成的Collection集合c。那在下面的程序里,在传入(ia,cn)参数...如下的程序,介绍泛型方法的,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 411,407
精华内容 164,562
关键字:

泛型问题