关于List泛型的强制转换
当我们从数据库中查询出一些数据,有时返回的结果可能是List<Object>类型,而我们清楚的知道它的准确类型是List<User>,可能我们想直接的去进行类型的转换,你可能会这么写:
//DbUtils.list("from User")返回是List<Object>类型
List<User> listUser= (List<User>)DbUtils.list("from User");
然而编辑器提示不可转换,这是为什么啊?我们项目开发中常常像下面这样去使用强转都可以的啊:
Object o= new Object();
User u= new User();
//向下转型
u= (User)o;
o= u;
看看上面的代码,是很正常的转换啊,即使父类向下转型为子类也是没问题的尽管存在类型安全的隐患,以下为我的推算,因为Object是所有类型的父级,所以任何对象都可以去转换成Object,因为有了这个继承的特性,有可能Object指向了一个User,而我们又需要使用这个User的方法,所以它支持存在安全隐患的强制向下转型,尽管存在安全隐患,但只要我们编码时稍微注意就可避免此隐患,因为我们知道这个Object指向的是一个User,所以有继承关系的向下类型转换是可避免的安全隐患。
但为什么List<User>和List<Object>转就不行了呢?
我们可以把List<User>和List<Object>想象为两个特殊(类似基本类型的存在)的类型(此处暂不知道如何解释,因为我对java的底层泛型处理这块知识并不了解,暂时先去这么理解),就例如:
String s= "a";
Integer i= 12;
i= (Integer)s;
你会发现字符串不能强转到整形,编译器禁止这么做是为了让类型更加安全,如果任何类型之间都能互相转换的话那将会导致类型的不安全,因为他们之间没有继承关系,如果贸然去转换将会发生不可避免的类型安全隐患,但是他们的父类都是Object,我们可以通过使用Object作为桥梁来间接转换:
String s= "a";
Integer i= 12;
Object o= s;
i= (Integer)o;
这样虽然编译期并没有报错,但运行期将会报类型转换异常,所以我们使用时一定要小心,只能强转给它的原类型。
既然我们无法直接转换,而又不想一个元素一个元素的去转类型,那么我们就间接的去转换吧,下面是间接转换的几种方式:
//1,此方法不可行,虽然编译期不报错,但运行期会转换失败,数组转换失败的原因与泛型强转失败应该同理,都是特殊(类似基本类型的存在)的类型,数组的强转在编译期检查不出来,使用的时候要注意这点。
List<User> listUser= Arrays.asList((User[])DbUtils.list("from User").toArray());
//2
List<User> listUser= Arrays.asList(DbUtils.list("from User").toArray(new User[0]));
//3,此方法不可行,虽然编译期不报错,但运行期会转换失败,数组转换失败的原因与泛型强转失败应该同理,都是特殊(类似基本类型的存在)的类型,数组的强转在编译期检查不出来,使用的时候要注意这点。
List<User> listUser= new LinkedList<User>();
Collections.addAll(listUser, (User[])DbUtils.list("from User").toArray());
//4
List<User> listUser= new LinkedList<User>();
Collections.addAll(listUser, DbUtils.list("from User").toArray(new User[0]));
//5,利用万物皆Object的思想来使用强转
List<User> listUser= (List<User>)(Object)DbUtils.list("from User");
//6
Object object= DbUtils.list("from User");
List<User> listCart= (List<User>)object;
我比较喜欢2和4的转换方式。
注意:基本类型的强转和引用类型的强转是有区别的,但这种区别很好区分,下面举一个小例子:
//1
int i= 1;
long l= 10;
//可行
i= (i)l;
//2
Integer i= new Integer(1);
Long l= new Long(10);
//不可行
i= (Integer)l;
以上观念为经验总结,并非总是正确的,如果你感觉我的见解有误,请及时纠正我。
求解释:
Object[] os= new Object[]{"a","b","c"};
String[] ss= (String[]) os;
System.out.println(ss);
即使利用万物皆对象的思想也是一样的结果。
Object[] os= new Object[]{"a","b","c"};
Object o= os;
String[] ss= (String[]) o;
System.out.println(ss);
为什么转换异常?
关于List泛型的强制转换的更多相关文章
- C#学习笔记二 (资源托管,泛型,数组和元组,运算符和类型强制转换)
托管和非托管资源 1.托管资源是指GC管理的内存空间,非托管资源是指文件句柄,网络连接,数据库连接等. 2.方法中临时申请的变量,被存放在栈中.栈存储非对象成员的值数据.例如在方法中有B b=new ...
- JAVA将数字字符串强制转换成整型变量----求参数之和实验代码(附流程图)
一.设计思想 先将参数个数输出,并利用循环结果将参数逐个输出,再将字符串强制转化成整型,利用循环结构相加求和 二.程序流程图 三.源程序代码 package demo; public class Co ...
- JS当心隐式的强制转换
JavaScript对类型错误出奇的宽容 3 + true; // 4 null + 3; // 3 运算符+(加号)的重载 运算符+既重载了数字相加,又重载了字符串连接操作.具体是数字相加还是字符串 ...
- C#高级编程笔记 2016年10月8日运算符和类型强制转换
1.checked和unchecked 运算符 C#提供了checked 和uncheckde 运算符.如果把一个代码块标记为checked, CLR就会执行溢出检查,如果发生溢出,就抛出overfl ...
- PHP是弱类型语言,自动转换,强制转换
强制转换: (int) - 转换成整型 (bool) - 转换.成布尔型 (float) - 转换成浮点型 (string) - 转换成字符串 (array) - 转换成数组 (object) - 转 ...
- Php中的强制转换详解
强制转换中分为两种,第一种就只临时转换,和永久转换.在临时转换中呢,首先可以通过第一中方式来显示,就是小括号的形式,临时转换成整型我们可以通过(int)都是这样的形式,或者是(integer)临时转换 ...
- c# 强制转换, 隐式转换, 显式转换
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- 黑马程序员-c语言-类型强制转换
强制转换的条件: 1.当所声明的类型不能满足所符值的变量时,需要转换声明的类型,以便能够存储变量. 例如:short存储的最大值为32767,但是所要符值大于32767时,short类型不符合,需要转 ...
- JavaScript学习笔记——数据类型强制转换和隐式转换
javascript数据类型强制转换 一.转换为数值类型 Number(参数) 把任何的类型转换为数值类型 A.如果是布尔值,false为0,true为1 B.如果是数字,转换成为本身.将无意义的后导 ...
随机推荐
- 什么是html5
HTML5是用于取代1999年所制定的 HTML 4.01 和 XHTML 1.0 标准的 HTML 标准版本,现在仍处于发展阶段,但大部分浏览器已经支持某些 HTML5 技术.HTML 5有两大特点 ...
- codeforces 725/C
Hidden Word time limit per test 2 seconds memory limit per test 256 megabytes input standard input o ...
- 越狱Season 1-Episode 13: End of the Tunnel
Season 1, Episode 13: End of the Tunnel -Fernando: The name is John Abruzzi. 名字是John Abruzzi A b r u ...
- jquery轻松操作CSS样式
$(this).click(function(){ if($(this).hasClass(“zxx_fri_on”)){ $(this).removeClass(“zxx_fri_on”); ...
- 黑马程序员——JAVA基础之System,Runtime,Date,Calendar,Math
------- android培训.java培训.期待与您交流! ---------- System: 类中的方法和属性都是静态的. out: 标准输出,默认是控制台. in:标准输入,默认是键盘 ...
- STL 简介,标准模板库
这篇文章是关于C++语言的一个新的扩展--标准模板库的(Standard Template Library),也叫STL. 当我第一次打算写一篇关于STL的文章的时候,我不得不承认我当时低估了这个话 ...
- opsview
nagios,cacti,opsview,prtg,zabbix http://www.opsview.com 1.需要注册一个账号,createyuan#sohu.com
- docker nodejs 基本应用
1. 安装docker 环境 2. nodejs 应用布局 package.json { "name": "docker-centos-hello", &qu ...
- Sublime Text3注册码 (备用)
复制如下三个任意一个正版注册码即可—– BEGIN LICENSE —–Andrew WeberSingle User LicenseEA7E-855605813A03DD 5E4AD9E6 6C0E ...
- 解决weblogic启动缓慢 linux系统随机数问题
这是SUN,JDK一个bug解决办法是在weblogic启动脚本里setDomainEnv.sh: 加入以下内容 JAVA_OPTIONS="${JAVA_OPTIONS} -Djava.s ...