网站首页 > java教程 正文
泛型应用值传递的问题?
在Java开发中像是如下的两种操作方式是不被允许的
public static void main(String[] args) {
//会出现编译错误
ArrayList<String> arrayList1 = new ArrayList<Object>();
//会出现编译错误
ArrayList<Object> arrayList2 = new ArrayList<String>();
}
首先来分析一下第一种情况
public static void main(String[] args) {
ArrayList<Object> objectArrayList = new ArrayList<Object>();
objectArrayList.add(new Object());
objectArrayList.add(new Object());
//会出现编译错误
ArrayList<String> arrayList1 = objectArrayList;
}
定义了一个Object的数组,然后添加两个Object对象之后将其赋值给了一个String类型的数组,这个时候编译会报错。这是为什么?
假设编译没有保存,当我们使用get方法获取数组对象的时候那么应该返回的是String类型的对象,但是在上面的代码中objectArrayList数组放入的是Object类型的对象,这样就会出现类型不配的异常。在Java中是不允许这样的操作的。
第二种情况可以写成如下的这种方式
public static void main(String[] args) {
ArrayList<String> stringArrayList = new ArrayList<String>();
stringArrayList.add(new String());
stringArrayList.add(new String());
//会出现编译错误
ArrayList<Object> arrayList1 = stringArrayList;
}
假设编译不会报错,那么在进行类型转换的时候,就是将String类型转换成了Object,我们也知道Object是Java中所有对象的父类,应该没啥问题?但是这样做的意义是什么呢?不如全部的对象都用Object代替好了。何必要转一圈回来还是使用Object代替呢?
所以在Java中为了避免这种情况的出现,在编译时候就对以上操作进行提示。
泛型变量不能是基本数据类型?
例如如下的操作在Java中是不允许的。
ArrayList<int> stringArrayList = new ArrayList<int>();
因为在进行类型擦除之后,ArrayList中的具体的对象会被替换为Object,但是对于基本数据类型来讲,它不是对象,所以需要使用它对应的引用类型来进行设置。
ArrayList<Integer> stringArrayList = new ArrayList<Integer>();
在静态方法和静态类中使用泛型?
在静态类或者静态方法中是不可以使用泛型类去声明泛型的参数,如下所示。
public class Test<T> {
public static T one;
public static T print(T one){
return null;
}
}
因为在泛型类中对于泛型的实例化是在定义的时候指定的,而对于静态变量或者是静态方法来讲,它是可以直接通过类类名进行调用的,所以不需要具体的对象,这个时候就会出现对象还没有确定,如何能够判断泛型类型是什么呢?所以就会编译报错。
如果将其泛型操作改成如下这种则是可以的。
public class Test<T> {
public static <T> T print(T one){
return null;
}
}
这是因为该方法是一个泛型的方法,在泛型方法中使用的T是自己在方法中定义的,而不是在泛型中的T。这个需要读者自己理解一下。
泛型相关面试题
1、Java中的泛型是什么?使用泛型的好处是什么?
泛型是泛化参数的类型机制,可以使得代码适用于各种数据类型,从编码的角度来讲,可以使得代码更加通用,例如在Java中的集合类型都是使用泛型。
泛型操作是一种在编译的时候进行类型确定的机制,它提供的机制是在编译时的类型安全,也就是说保证了泛型在编译的时候使用到正确的类型,避免出现在使用的时候出现类型不匹配的问题。
2、泛型是如何工作的?什么是类型擦除?
上面也提到了,泛型的正常执行是依赖在编译的时候对类型进行了检查,这样在进行类型擦除之后可以通过强制类型转换来进行相关的操作。
在编译的时候会擦除所有的类型相关的信息,所以在运行的时候不会存在任何的类型相关信息,例如List<String>在完成类型擦除之后只会存在一个List,至于List中的内容就是根据具体实际使用来决定了。
为什么要进行类型擦除?是为了防止类型膨胀。
3、什么是限定性通配符?什么是非限定性通配符?
在使用泛型的时候限定性的通配符是对类型进行进行了限定,有如下两种
- <? extends T> 通过这种方式来确保参数必须是T的子类型。
- <? super T> 通过这种方式来限定参数类型必须是T的父类型。
上面两种方式一种限定了上界,一种限定了下界。在进行泛型设置的时候必须采用指定的类型来进行初始化,否则就会编译错误。
而<?>就表示非限定性通配符,也就是说它可以用任意类型来代替。
4、List<Object>、List<String>和原始的List之间有什么区别?
主要的区别就是对于参数类型安全性的检查,如果带了参数则会对参数类型进行检查,如果使用的是Object则会接受任意类型的参数。主要是大家要理解原始类型与泛型的区别。
- 上一篇: Java泛型机制详解;这些你都知道吗?
- 下一篇: 深入理解 Java 泛型(java泛型的实现原理)
猜你喜欢
- 2024-10-16 Java泛型详解(完整版)必看(java 泛型 t)
- 2024-10-16 Java泛型最全总结(java泛型的实现原理)
- 2024-10-16 Java高级面试:Java的泛型实现机制是怎么样的?
- 2024-10-16 深入理解 Java 泛型(java泛型的实现原理)
- 2024-10-16 Java泛型机制详解;这些你都知道吗?
- 2024-10-16 Java中的泛型是什么?(java里面的泛型)
- 2024-10-16 学习廖雪峰的JAVA教程---泛型(使用泛型)
- 2024-10-16 Java泛型的好处及实现原理详解(java里泛型)
- 2024-10-16 java中的泛型是什么(java中泛型的理解)
- 2024-10-16 一句话概述什么是泛型,教你直白理解Java泛型
你 发表评论:
欢迎- 最近发表
-
- Java常量定义防暴指南:从"杀马特"到"高富帅"的华丽转身
- Java接口设计原则与实践:优雅编程的艺术
- java 包管理、访问修饰符、static/final关键字
- Java工程师的代码规范与最佳实践:优雅代码的艺术
- 编写一个java程序(编写一个Java程序计算并输出1到n的阶乘)
- Mycat的搭建以及配置与启动(mycat部署)
- Weblogic 安装 -“不是有效的 JDK Java 主目录”解决办法
- SpringBoot打包部署解析:jar包的生成和结构
- 《Servlet》第05节:创建第一个Servlet程序(HelloSevlet)
- 你认为最简单的单例模式,东西还挺多
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)