Kotlin基本类型自动装箱出现问题解决办法

Kotlin基本类型自动装箱出现问题解决办法

问题

在Kotlin官方文档介绍基本类型时,给我们说明了在有些情况下会对基本类型自动进行装箱操作。 但是具体是如何进行装箱,以及何时进行装箱缺没有提供详细介绍。只是提供了一个例子,如下:

val a: Int = 10000
print(a === a) // Prints 'true'
val boxedA: Int? = a
val anotherBoxedA: Int? = a
print(boxedA === anotherBoxedA) // !!!Prints 'false'!!!

对于上述代码,废了好大力气 写了好多demo才搞清楚。 接下来先通过几个简单的栗子来理解一下Kotlin是如何进行装箱操作的

####**第一个栗子**

fun main(args: Array<String>) {
 test1()
}

fun test1() {
 val i: Int = 1000
 println(i)
}

给大家提供一点技巧,在看不懂Kotlin是如何编译运行的情况下,我们可以先将其反编译成Java字节码,对于Java我们就驾轻就熟啦。具体做法就是 1 显示Kotlin的字节码 ![这里写图片描述](http://img.blog.csdn.net/20171013135245711?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenhtMzE3MTIyNjY3/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 2 将Kotlin字节码反编译成Java字节码 ![这里写图片描述](http://img.blog.csdn.net/20171013135324119?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenhtMzE3MTIyNjY3/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 通过这种方法,将上面的test1()方法反编译之后得出如下字节码

public static final void test1() {
  short i = 1000;
  System.out.println(i);
 }

可以看出Kotlin编译器将 i 单纯的看做是一个基本类型short,并将其打印

再举个栗子

fun main(args: Array<String>) {
 test2()
}

fun test2() {
 val i: Int? = 1000
 println(i)
}

看到test1和test2的区别了吗?? 在test2中多了一个 ?

val i: Int? = 1000

这个“`?“`代表的意思是这个i可以被赋值为null, 既然可以是null,那就不能是原始类型,只能是对象,因此Kotlin会自动的为其进行装箱操作。因此反编译test2之后,我们会得到如下字节码

 public static final void test2() {
  Integer i = Integer.valueOf(1000);
  System.out.println(i);
 }

分析

理解了上述两个小栗子之后,在回头看一下官方提供的demo,就可以理解了。我们不妨自己也写一个类似的代码

fun test3() {
 //Kotlin并不会自动装箱
 val i: Int = 1000

 println(i)

 //因为j和k都被当做对象操作,因此会将i进行装箱做操,然后复制给j、k
 val j: Int? = i
 val k: Int? = i

 println(j === k)
}

反编译成java字节码之后结果同我们猜想的一致:

public static final void test3() {
  short i = 1000;
  System.out.println(i);
  Integer j = Integer.valueOf(i);
  Integer k = Integer.valueOf(i);
  boolean var3 = j == k;
  System.out.println(var3);
}

总结

注:在Kotlin中,字符类型不是基本数值类型,是一个独立的数据类型。

上面的整形类型的表示方式并没有使用int、double等java中的关键字,而是使用了封装类来表示 这是因为在Kotlin中一切都是对象(没有如同java中的基本类型)。 当我们在代码中使用整形数字的时候,Kotlin会自动的将其进行装箱操作

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

时间: 2017-10-12

Kotlin基本类型自动装箱一点问题剖析

问题 在Kotlin官方文档介绍基本类型时,给我们说明了在有些情况下会对基本类型自动进行装箱操作. 但是具体是如何进行装箱,以及何时进行装箱缺没有提供详细介绍.只是提供了一个例子,如下: val a: Int = 10000 print(a === a) // Prints 'true' val boxedA: Int? = a val anotherBoxedA: Int? = a print(boxedA === anotherBoxedA) // !!!Prints 'false'!!!

详解Java 自动装箱与拆箱的实现原理

什么是自动装箱和拆箱 自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱.因为这里的装箱和拆箱是自动进行的非人为转换,所以就称作为自动装箱和拆箱.原始类型byte, short, char, int, long, float, double 和 boolean 对应的封装类为Byte, Short, Character, Integer, Long, Float, Dou

java自动装箱拆箱深入剖析

这个是jdk1.5以后才引入的新的内容,作为秉承发表是最好的记忆,毅然决定还是用一篇博客来代替我的记忆: java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的(在这种情况下包装成为装箱,解包装称为拆箱): 其实按照我自己的理解自动装箱就可以简单的理解为将基本数据类型封装为对象类型,来符合java的面向对象:例如用int来举例: 复制代码 代码如下: //声明一个Integer对象 Integer num = 10; //以上的声明就是用到了自动的装箱:解析为 Integer nu

浅谈Java自动装箱与拆箱及其陷阱

在本文中,笔者向大家介绍下Java中一个非常重要也非常有趣的特性,就是自动装箱与拆箱,并从源码中解读自动装箱与拆箱的原理,同时这种特性也留有一个陷阱.开发者如果不注意,就会很容易跌入这个陷阱. 自动装箱(Autoboxing) 定义 大家在平时编写Java程序时,都常常以以下方式来定义一个Integer对象: Integer i=100; 从上面的代码中,大家可以得知,i为一个Integer类型的引用,100为Java中的基础数据类型(primitive data type).而这种直接将一个基

java编程中自动拆箱与自动装箱详解

什么是自动装箱拆箱 基本数据类型的自动装箱(autoboxing).拆箱(unboxing)是自J2SE 5.0开始提供的功能. 一般我们要创建一个类的对象实例的时候,我们会这样: Class a = new Class(parameter); 当我们创建一个Integer对象时,却可以这样: Integer i = 100; (注意:不是 int i = 100; ) 实际上,执行上面那句代码的时候,系统为我们执行了:Integer i = Integer.valueOf(100); (感谢@

详解Java包装类及自动装箱拆箱

Java包装类 基本类型 大小 包装器类型 boolean / Boolean char 16bit Boolean byte 8bit Byte short /16bit Short int 32bit Integer long 64bit Long float 32bit Float double 64bit Double void / Void Java 的包装类有两个主要的目的: Java包装类将基本数据类型的值"包装"到对象中,对基本数据类型的操作变为了对对象进行操作,从而使

Java中自动装箱、拆箱引起的耗时详解

什么是自动装箱,拆箱 先抛出定义,Java中基础数据类型与它们的包装类进行运算时,编译器会自动帮我们进行转换,转换过程对程序员是透明的,这就是装箱和拆箱,装箱和拆箱可以让我们的代码更简洁易懂 耗时问题 在说 Java 的自动装箱和自动拆箱之前,我们先看一个例子. 这个错误我在项目中犯过(尴尬),拿出来共勉! private static long getCounterResult() { Long sum = 0L; final int length = Integer.MAX_VALUE; f

Java基础之自动装箱,注解操作示例

本文实例讲述了Java基础之自动装箱,注解操作.分享给大家供大家参考,具体如下: 示例代码: 手动装箱,手动拆箱 Integer iOb=new Integer(100);//手动装箱 int i=iOb.intValue(); //手动拆箱 System.out.println(i+" "+iOb); 自动装箱,自动拆箱 Integer iOb=1000; int i=iOb; System.out.println(i+" "+iOb); 静态导入:可以直接通过静

详解Java 自动装箱与自动拆箱

包装器 有些时候,我们需要把类似于int,double这样的基本数据类型转成对象,于是设计者就给每一个基本数据类型都配置了一个对应的类,这些类被称为包装器. 包装器整体来说分为四大种: Number,Number类派生出了Integer,Double,Long,Float,Short,Byte这六个小类分别代表了int,double,long,float,short,byte这六种基本数据类型. Character,对应的基本数据类型是char. Void,对应的是关键字void,这个类我们会经