孙悟空的七十二变是那般?--java类型的七十二变揭秘

故事背景

  在《西游记》原著第六回,孙悟空大闹天宫反下界,玉帝派十万天兵围剿,却被打得落花流水。玉帝不得不放下架子,请自己外甥二郎神回来支援。孙悟空与二郎神本事差不多,两人斗得不分胜负,但二郎神有梅山六兄弟助阵,而孙的阵营只是乌合之众。两人战斗正酣时,孙悟空闻后方阵营攻破,猴子被打散,心中发慌败下阵来。

  为了逃脱梅山六兄弟的围追堵截,孙悟空摇身一变,变作一个麻雀,飞在树桃头钉住。这个变化太low了,二郎神一眼就识破假象,立即变成饿鹰扑了过来。孙悟空只得又变成大鹚老冲天而起,二郎神则变成大海鹤,钻上云宵来嗛……

  几经斗法,孙悟空最后变成一座土地庙,牙齿作门扇,舌头变菩萨,眼睛变窗棂,但尾巴却不好收拾,只得竖在后面,变成一根旗竿。这个变化迷惑性很大,一般神仙还真看不破。不料二郎神赶到,见一根旗竿立在后面,顿时笑了:“是这猢狲了!他今又在那里哄我。我也曾见庙宇,更不曾见一个旗竿竖在后面的。断是这畜生弄谊!他若哄我进去,他便一口咬住。我怎肯进去?等我掣拳先捣窗棂,后踢门扇!”孙悟空一听,妈妈呀,这二郎神好狠!“门扇是我牙齿,窗棂是我眼睛;若打了牙,捣了眼,却怎么是好?”于是赶紧收了法相,逃命去了。

  这七十二变的最大缺陷是:若是变飞禽、走兽、花木、器皿、昆虫之类,可以连身子一起变;但如果变人物,却只是头脸变了,身子变不过来,还有一身黄毛,两块红股,一条尾巴。原因:七十二变化本身就是人研制出来的,也是为人量身打造的,故孙悟空学会后会存在缺陷。

java中的七十二变

我们看一下,java的七十二般变化吧!

public class Multicast{
public static void main (String[] args){
System.out.println((int)(char)(byte) -1);
}
}

上面的程序以int 数值-1 开始,然后从int转型为byte,之后转型为char,最后转型回int。第一个转型将数值从32 位窄化到了8 位,第二个转型将数值从8 位拓宽到了16 位,最后一个转型又将数值从16 位拓宽回了32 位。这个数值最终是回到了起点吗?

是不是想起了《看我七十二变》:

  看我七十二变

  今天新鲜改变再见

  美丽极限爱漂亮没有终点

  追求完美的境界

  人不爱美天诛地灭

  别气馁旧观念抛到一边

  现在就开始改变

  麻雀也能飞上青天

运行看结果吧

65535

为什么会这样呢?我们将程序一步步分开来看:

    public static void main (String[] args){
        int i=-1;
        byte b=(byte)-1; //1
        char c=(char)b; //2
        int r=(int)c; //3
        System.out.println(r);
        }

第一步:int转byte

  byte b=-1 窄化后没有改变值

第二步:byte转char

  从byte 到char 的转型稍微麻烦一点,因为byte 是一个有符号类型,而char是一个无符号类型。在将一个整数类型转换成另一个宽度更宽的整数类型时,通常是可以保持其数值的,但是却不可能将一个负的byte 数值表示成一个char。因此,从byte 到char 的转换被认为不是一个拓宽原始类型的转换,而是一个拓宽并窄化原始类型的转换(widening and narrowing primitive conversion):byte 被转换成了int,而这个int 又被转换成了char

char c=65535//符号扩展

第三步:char转int

  int r=65535//零扩展

因为byte 是一个有符号的类型,所以在将byte 数值-1 转换成char 时,会发生符号扩展。作为结果的char 数值的16 个位就都被置位了,因此它等于2的16次方-1,即65535。

从char 到int 的转型也是一个拓宽原始类型转换,它将执行零扩展而不是符号扩展。作为结果的int 数值也就成了65535,

这正是程序打印出的结果。

深入:java如何七十二变?

jls-5强制类型转换,定义标识如下:

- 表示不运行任何强制类型转换

≈ 表示标识抓获(§5.1.1)

ω 表示拓宽基本类型转换 (§5.1.2)

η 表示窄化基本类型转换 (§5.1.3)

ωη 表示拓宽和窄化类型转换 (§5.1.4)

⇑ 表示拓宽引用类型转换 (§5.1.5)

⇓ 表示窄化引用类型转换(§5.1.6)

⊕ 表示装箱转换 (§5.1.7)

⊗表示拆卸类型转换 (§5.1.8)

到基本类型的强制类型转换

到引用类型的强制类型转换

更详细的资料请参照JSL5描述,链接地址见参考资料【3】

参考资料

【1】https://baike.baidu.com/tashuo/browse/content?id=1275b5b5f23ff153017f164c&fr=qingtian&lemmaId=11061

【2】https://baike.baidu.com/item/%E4%B8%83%E5%8D%81%E4%BA%8C%E5%8F%98/11061?fr=aladdin#2_2

【3】https://docs.oracle.com/javase/specs/jls/se12/html/jls-5.html

【4】java解惑

原文地址:https://www.cnblogs.com/davidwang456/p/11623889.html

时间: 2025-01-12 19:08:26

孙悟空的七十二变是那般?--java类型的七十二变揭秘的相关文章

oracle中数据类型对应java类型

地址: http://otndnld.Oracle.co.jp/document/products/oracle10g/102/doc_cd/Java.102/B19275-03/datacc.htm#BHCJBJCC SQL数据类型 JDBC类型代码 标准的Java类型 Oracle扩展的Java类型   1.0标准的JDBC类型:     CHAR java.sql.Types.CHAR java.lang.String oracle.sql.CHAR VARCHAR2 java.sql.T

Thinking in Java -- 类型信息RTTI

Thinking in Java – 类型信息 个人感觉 java 中的比較难的部分了,在看了些netty源代码发现事实上这块很实用. 这章重点是RTTI和反射.先说下自己的理解 RTTI是执行时识别.在c++中是用virtual来实现的,在编译期会忽略对象的详细类型信息,假定我们已经知道,并在执行时详细识别. Java反射机制实在执行状态中,对于随意一个类,都能够知道这个类的全部属性和方法.对于随意一个对象.都能够调用它的随意一个方法和属性,这样的动态获取的信息以及动态调用对 象的方法的功能称

java类型擦除(Java Type Erasure Mechanism)

在JDK5之后java提供了泛型(Java Genertics),允许在定义类的时候使用类型作为参数.泛型广泛应用于各类集合中.本文对其以及其用法进行介绍. 1.一个常见的错误 下面例子中,用List<Object>类型的参数来接收List<String>. public class Main { public static void main(String[] args) throws IOException { ArrayList<String> al = new

java类型与Hadoop类型之间的转换

java基本类型与Hadoop常见基本类型的对照Long LongWritableInteger   IntWritableBoolean   BooleanWritable String Text Java类型如何转化为Hadoop基本类型? 调用hadoop类型的构造方法,或者调用set()方法. new LongWritable(123L); hadoop基本类型如何转化为java类型? 对于Text,需要调用toString()方法,其他类型调用get()方法. 以后继续,深入

java类型与jdbc类型对应表

  java.sql.Types 值 Java 类型 IBM DB2 Oracle Sybase SQL Informix IBM Content Manager   BIGINT java.lang.long BIGINT NUMBER (38, 0) BIGINT BIGINT INT8 DK_CM_BIGINT   BINARY byte[] CHAR FOR BIT DATA RAW BINARY IMAGE BYTE DK_CM_BLOB   BIT java.lang.Boolean

JNI中java类型的简写

  在JNI中,当我们使用GetFieldID/GetStaticFieldID或GetMethodID/GetStaticMethodID及定义JNINativeMethod等时,我们需要表示成员变量的类型,或函数传入参数或返回的类型.JNI把Field的类型,或函数传入参数或返回值的类型进行简写以char*的形式进行表示.      对于成员变量,直接用java类型的简写表示成员变量的类型就可以      比如:"I"表示该成员变量是Int类型                 &q

类型-hibernate与java类型

在hibernate的映射文件中type属性支持两种类型    java类型    hibernate类型 说明:java类型效率更高   hibernate-3.5.6-Final-dist/hibernate-distribution-3.5.6-Final/documentation/manual/zh-CN/html_single/index.html#mapping-types 5.2.2. 基本值类型 内置的 basic mapping types 可以大致地分类为: integer

oracle字段 Hibernate映射类型 java类型

oracle字段 Hibernate映射类型 java类型 number big_decimal java.math.BigDecimal number(1) boolean Boolean number(2)2至4之间 byte Byte number(8)4至8之间 integer Integer numbernumber(10)8以上 long Long

SQLServer,MySQL和Java类型的映射关系

下面是SQL Server, JDBC Type, 以及JAVA类型的对应关系: S SQL Server Typeype JDBC Type JDBC Type Java Type Java Type Mock Default value 说明说明 bigint BIGINT long 0   timestamp BINARY byte[] Null Use INSERT with a column list to exclude the timestamp column, or insert