`
xwood
  • 浏览: 100678 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

JAVA中的类型转换问题

阅读更多
    虽然在Java中有N种情况的数据类型转换,但从从内存处理的角度来说,其实都是一个问题——变量的可见范围,也就是这个变量所代表的内存区域。下面就从以下四个方面说明一下。

一、强制类型转换
    强制类型转换是体现这范围变化最明显的地方。
    强制类型是指基本数据类型从占用内存多的向占用内存少的类型转换。比如64bit的long向32bit的int转换。假设Java采用低位优先(还有待查明,验证)存储数据,则在从long转为int的过程中,其高位32bit的数据就会被隐藏或者叫截断,因为系统认为int类型只有32bit,所以,它在访问int类型的数据的时候也只会访问32bit的内存。这样,剩下的32bit就直接被忽略掉了。这也是为什么我们在进行强制类型转换的时候需要人为控制,或者两种相互转换的类型大小相同的原因。具体可运行如下示例代码:
  /*
		 * 1.引用类型间的强制转换
		 * 转换之间的两个数据的原类型(原类型是指数据本身的类型,如 A a = new B(),则a的实际类型为B而非A)必须是可转换关系,
		 * 即转换的目标类型与被转换类型相同,或者转换的目标类型是被转换类型的父类,这种情况称为“向上转型”
		 */
		//(一)转换的目标类型与被转换类型相同
		Object a = new Object();
		a = new BigDecimal(1.0);
		try{
			String b = (String)a;
		}catch(ClassCastException e){
			System.out.println("error1 -- program throws a error when Object a is casted to String b.");
		}
		try{
			BigDecimal c = (BigDecimal)a;
		}catch(ClassCastException e){
			System.out.println("error2 -- program throws a error when Object a is casted to BigDemal c.");
		}
		
		//(二)转换的目标类型与被转换类型存在继承关系
		a = new HashMap();
		try{
			Map b = (Map)a;
		}catch(ClassCastException e){
			System.out.println("error3 -- program throws a error when Object a is casted to Map b.");
		}
		
		try{
			LinkedHashMap c = (LinkedHashMap)a;
		}catch(ClassCastException e){
			System.out.println("error4 -- program throws a error when Object a is casted to LinkedHashMap c.");
		}
		
		/*
		 * 2.基本类型间的强制转换
		 */
		float aa = 1.0f;
		int bb = (int)aa;
		System.out.println("int type bb :" + bb);
		double cc = (double)aa;
		System.out.println("double type cc:" + cc + "-------size:");


二、自动转换
    当占用内存少的数据类型向占用内存多的数据类型转换的时候,我们称为自动转换。它和强制类型转换恰好是一个相反的过程。强制类型转换是将高位数据截去,而自动转换则是为小数据类型分配更多的高位内存,以0填充。

三、向上转型
    在Java中还有向上转型与向下转型的说法,这主要是对类的继承而言。
    向上转型是指子类转型为父类,就好比让一只鸭子变成一只鸟,其实它本就是一只鸟。
    从内存范围的角度来说,假如鸭子类型需要取10个属性及5个方法的内存地址。那么这里面肯定包括鸟的3个属性地址及2个方法地址。所以,在整个转换过程中只是少取了一些内存地址而已。

四、向下转型
    向下转型也是需要人为控制的。它是指实体从父类型转换为子类型的过程。还以鸭子和鸟为例,这次就是把一只鸟变成一只鸭子了。如果这只鸟本就是一只鸭子,那这个过程还可以实现,就是把外面的伪装去掉,变成其原来的样子而已。但如果它不是一只鸭子,是一只麻雀。这就麻烦了。因为我们还得给它加些肉,羽毛也少了,还得加羽毛,还得变色。这是一个创造的过程,不得程序中一句下面的代码就可以完成的:
鸟 b = new 鸟();
鸭子 a = (鸭子) b;//b是一只鸟,它不是鸭子

    从内存范围的角度来说,不正确的向下转型就是要系统创造性的给转型后的实体加一些引用属性或方法的内存地址映射,但这个过程,系统是不知道如何去完成的,所以它就只能报错。






分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics