很多人对java类型之间的转换,强转,那是傻傻分不清楚。
1.基本类型:
int a=0;
float a=8.2 //error,这个不能被编译通过
//我们这样写就可以了
float a=(float)8.2;//把double 型的强制转换为float
2.引用类型( 上(父类)-----强转--->>下(子类) 下(子类) -------->> 上(父类) )
具有继承关系的类或接口 向下转型需要强转 就是父类转成子类。父亲在上,儿子在下,这叫做向下转型
Object obj = null;//java中所有类的老大,根
String str = null;
str = (String) obj;
obj = str;
那么为什么Object类型转成String需要强制转换?
因为Object是java类型的根类,String 是继承自Object,是Object的子类。
子类继承了父类的所有属性,所以子类转为父类,不需要强转;而父类可能不具备子类的所有属性,因此需要强制转换。
就好像:苹果肯定是果子,但果子不一定是苹果。如果想让某果子变成苹果,只好强制性称呼某个果子为“苹果”。
这对于具有继承关系的接口和类之间同样适用。如:
ArrayList<String> aList = null;//ArrayList<E> implement List<E>
List<String> list = null;//List<E> extends Collection<E>
Collection<String> colle = null;
aList = (ArrayList<String>) list;//下←上,强转
aList = (ArrayList<String>) colle;//下←上,强转
list = (List<String>) colle;//下←上,强转
list = aList; //父类←子类,上←下
colle = list;//父接口←子接口,上←下
colle = aList;//父接口←子类实现,上←下
一个超类能做的东西,其子类也能做,而一个子类能做的东西超类不一定能做,所以就有这样的规则:
(1).一个子类的对象可以强制转换成为其超类的对象;
(2).一个超类的对象如果强制转换成子类的对象将在运行的时候有异常抛出;
(3).如果不是同一继承树上的类强制转换,将产生编译错误.
例如:
class A {}
class B extends A{}
class C {}
B b=new B();
A a=(A)b;//被b引用的对象强制转换为类A的对象,类B的对象具有类A对象的性质,所以可以转换成功
a=new A();
b=(B)a;//原本是类A的对象,可能不具备类B的性质,这样会在运行的时候产生异常.
C c=new C();
a=(A)c;//如果c不是同一继承树类编译的时候将会产生错误,
因此, 我们应该养成一个良好的编程习惯,在进行类型转换之前,先看一下是否能成功转换.
这个过程简单地使用instanceof运算符就可以实现.例如:
if(staff[0] instanceof Manger){
boss = (Manger)staff[0];
...
}
注意: List<String> 不能强转成 List<Object> Object[] 不能强转成String[]
Set<String> set = new HashSet<>();
set.add("abc");
set.add("bbc");
set.add("cdd");
//错误!!!!!
String[] strsWrong = (String[]) set.toArray();
System.err.println(Arrays.toString(strsWrong));
//正确
String[] strsRight = set.toArray(new String[set.size()]);
System.err.println(Arrays.toString(strsRight));