189 8069 5689

java装包拆包代码 java 拆箱装箱

java 什么是拆箱和装箱,拆箱和装箱 嘛用啊???

详解Java的自动装箱与拆箱(Autoboxing and unboxing)

创新互联坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站制作、网站设计、外贸网站建设、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的丰宁网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!

一、什么是自动装箱拆箱 

很简单,下面两句代码就可以看到装箱和拆箱过程

//自动装橡此箱

Integer total = 99;

//自定拆箱

int totalprim = total;

简单一点说,装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。

下面我们来看看需要装箱拆箱的类型有哪些:

这个过程是自动执行的,那么我们需要看看它的执行过程:

public class Main {

public static void main(String[] args) {

//自动装箱

Integer total = 99;

//自定拆箱

int totalprim = total;

}

}

反编译class文件之后得到如下内容:

javap 告卜-c StringTest

Integer total = 99; 

执行上面那句代码的时候,系统为我们执行了: 

Integer total = Integer.valueOf(99);

int totalprim = total; 

执行上面那句代码的时候,系统为我们执行了: 

int totalprim = total.intValue();

我们现在就以Integer为例,来分析一下它的源码: 

1、首先来看看Integer.valueOf函数

public static Integer valueOf(int i) {

return  i = 128 || i  -128 ? new Integer(i) : SMALL_VALUES[i + 128];

}

它会首先判断i的大小:如果i小于-128或者大于等于128,就创建一个Integer对象,否则执行SMALL_VALUES[i + 128]。

首先我们来看看Integer的构造函数:

private final int value;

public Integer(int value) {

this.value = value;

}

public Integer(String string) throws NumberFormatException {

this(parseInt(string));

}

它里面定义了一个value变量,创建一个Integer对象,就会给这个变量初始化。第二个传入的是一个String变量,它会先把它转换成一个int值,然后进行初始化。

下面看看SMALL_VALUES[i + 128]是什么东西:

private static final Integer[] SMALL_VALUES = new Integer[256];

它是一个静态的Integer数组对象,也就是说最终valueOf返回的都是一个Integer对象。

所以我们这里可以总结一点:装箱的过程会创建对应的对象,这个会消耗内存,所以装箱的过程会增加内存的消耗,影响性能。

2、接着看看intValue函数

@Override

public int intValue() {

return value;

}

这个很简单,直接返回value值即可。

二、相关问题 

上面我们看到在Integer的构造函数中,它分两种情况: 

1、i = 128 || i -128 ===== new Integer(i) 

2、i 128 i = -128 ===== SMALL_VALUES[i + 128]

private static final Integer[] SMALL_VALUES = new Integer[256];

SMALL_VALUES本来已经被创建好,也就是说在i = 128 || i -128是会创建不同的对象,在i 128 i = -128会根据i的值返回已经创建好的指定的对象。

说这些可能还不是很明白,下面我们来举个例子吧:

public class Main {    public static void main(String[] args) {

袜如穗    Integer i1 = 100;

Integer i2 = 100;

Integer i3 = 200;

Integer i4 = 200;

System.out.println(i1==i2);  //true

System.out.println(i3==i4);  //false

}

}

代码的后面,我们可以看到它们的执行结果是不一样的,为什么,在看看我们上面的说明。 

1、i1和i2会进行自动装箱,执行了valueOf函数,它们的值在(-128,128]这个范围内,它们会拿到SMALL_VALUES数组里面的同一个对象SMALL_VALUES[228],它们引用到了同一个Integer对象,所以它们肯定是相等的。

2、i3和i4也会进行自动装箱,执行了valueOf函数,它们的值大于128,所以会执行new Integer(200),也就是说它们会分别创建两个不同的对象,所以它们肯定不等。

下面我们来看看另外一个例子:

public class Main {    public static void main(String[] args) {

Double i1 = 100.0;

Double i2 = 100.0;

Double i3 = 200.0;

Double i4 = 200.0;

System.out.println(i1==i2); //false

System.out.println(i3==i4); //false

}

}

看看上面的执行结果,跟Integer不一样,这样也不必奇怪,因为它们的valueOf实现不一样,结果肯定不一样,那为什么它们不统一一下呢? 

这个很好理解,因为对于Integer,在(-128,128]之间只有固定的256个值,所以为了避免多次创建对象,我们事先就创建好一个大小为256的Integer数组SMALL_VALUES,所以如果值在这个范围内,就可以直接返回我们事先创建好的对象就可以了。

但是对于Double类型来说,我们就不能这样做,因为它在这个范围内个数是无限的。 

总结一句就是:在某个范围内的整型数值的个数是有限的,而浮点数却不是。

所以在Double里面的做法很直接,就是直接创建一个对象,所以每次创建的对象都不一样。

public static Double valueOf(double d) {

return new Double(d);

}

下面我们进行一个归类: 

Integer派别:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。 

Double派别:Double、Float的valueOf方法的实现是类似的。每次都返回不同的对象。

下面对Integer派别进行一个总结,如下图:

下面我们来看看另外一种情况:

public class Main {    public static void main(String[] args) {

Boolean i1 = false;

Boolean i2 = false;

Boolean i3 = true;

Boolean i4 = true;

System.out.println(i1==i2);//true

System.out.println(i3==i4);//true

}

}

可以看到返回的都是true,也就是它们执行valueOf返回的都是相同的对象。

public static Boolean valueOf(boolean b) {

return b ? Boolean.TRUE : Boolean.FALSE;

}

可以看到它并没有创建对象,因为在内部已经提前创建好两个对象,因为它只有两种情况,这样也是为了避免重复创建太多的对象。

public static final Boolean TRUE = new Boolean(true);

public static final Boolean FALSE = new Boolean(false);

上面把几种情况都介绍到了,下面来进一步讨论其他情况。

Integer num1 = 400;  

int num2 = 400;  

System.out.println(num1 == num2); //true

说明num1 == num2进行了拆箱操作

Integer num1 = 100;  

int num2 = 100;  

System.out.println(num1.equals(num2));  //true

我们先来看看equals源码:

@Override

public boolean equals(Object o) {

return (o instanceof Integer)  (((Integer) o).value == value);

}

我们指定equal比较的是内容本身,并且我们也可以看到equal的参数是一个Object对象,我们传入的是一个int类型,所以首先会进行装箱,然后比较,之所以返回true,是由于它比较的是对象里面的value值。

Integer num1 = 100;  

int num2 = 100;  

Long num3 = 200l;  

System.out.println(num1 + num2);  //200

System.out.println(num3 == (num1 + num2));  //true

System.out.println(num3.equals(num1 + num2));  //false

1、当一个基础数据类型与封装类进行==、+、-、*、/运算时,会将封装类进行拆箱,对基础数据类型进行运算。 

2、对于num3.equals(num1 + num2)为false的原因很简单,我们还是根据代码实现来说明:

@Override

public boolean equals(Object o) {

return (o instanceof Long)  (((Long) o).value == value);

}

它必须满足两个条件才为true: 

1、类型相同 

2、内容相同 

上面返回false的原因就是类型不同。

Integer num1 = 100;

Ingeger num2 = 200;

Long num3 = 300l;

System.out.println(num3 == (num1 + num2)); //true

我们来反编译一些这个class文件:javap -c StringTest 

可以看到运算的时候首先对num3进行拆箱(执行num3的longValue得到基础类型为long的值300),然后对num1和mum2进行拆箱(分别执行了num1和num2的intValue得到基础类型为int的值100和200),然后进行相关的基础运算。

我们来对基础类型进行一个测试:

int num1 = 100;

int num2 = 200;

long mum3 = 300;

System.out.println(num3 == (num1 + num2)); //true

上面就说明了为什么最上面会返回true.

所以,当 “==”运算符的两个操作数都是 包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。

通过上面的分析我们需要知道两点: 

1、什么时候会引发装箱和拆箱 

2、装箱操作会创建对象,频繁的装箱操作会消耗许多内存,影响性能,所以可以避免装箱的时候应该尽量避免。

我有一个微信公众号,经常会分享一些Java技术相关的干货文章,还有一些学习资源。

如果你需要的话,可以用微信搜索“Java团长”或者“javatuanzhang”关注。

如何将java源代码打包生成jar?

工具:

eclipse

方法:

1、启首旦动eclipse;

2、在eclipse中建立好工程与类并旦手写好代码;

3、点击“File-Export”;

4、在弹击的界面中选择“Java-JAR file”,再点击“Next”;

5、选择要打包的文件,再点击“Browse”;

6、在弹出的界面中选择好打包后的文件的存放路径,再输入文件者迟扰名,最后点击“保存”;

7、点击“Finish”;

8、打包成功。

什么是java中的自动装箱和自动拆箱

java自动装箱和拆箱

基本数据类型,如int,float,double,boolean,char,byte,不具备对象的特征,不能调用世如锋方法。

装箱:将基本类型转换成包装类对象

int i=10;

Integer x=new Integer(i);手动装箱

Integer y=10;自动装箱

拆箱:将包装类对象转换成基本类型的值

Integer j=new Integer(8);

int m=j.intValue();//手动拆箱

int n=j;//自动拆箱

java为什么要引入自动装箱和拆箱的功能?又是怎么实现的呢?

主要是用于java集合中,ListInteter list=new ArrayListInteger();

list集合如果要放整数的话,只能放对象,不能放基本类型,因此需要将整数自动装箱成对象。

实现原理:javac编译器的语法糖

public class Main {

public static void main(String[] args) {

Integer i1 = 100;

Integer i2 = 100;

Integer i3 = 200;

Integer i4 = 200;

System.out.println(i1==i2);

System.out.println(i3==i4);

}

}

//结果为:true false

在通过Integer.valueOf()方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用(位于堆对象池中);否则创建一个新的Integer对象(创建在java堆中)。上搜晌面的代码中i1和i2的数值为100,因此会直接从cache中取已经存在的对象,所以i1和i2指向的是同一个对象,而i3和i4则是分别指向不同的对象。

public class Main {

public static void main(String[] args) {

Double i1 = 100.0;

Double i2 = 100.0;

Double i3 = 200.0;

Double i4 = 200.0;

System.out.println(i1==i2);

System.out.println(i3==i4);

}

}

//结果为:false false

为什么Double类的valueOf方法会采用橡丛与Integer类的valueOf方法不同的实现呢?很简单:在某个范围内的整型数值的个数是有限的,而浮点数却不是。

public class Main {

public static void main(String[] args) {

Boolean i1 = false;

Boolean i2 = false;

Boolean i3 = true;

Boolean i4 = true;

System.out.println(i1==i2);

System.out.println(i3==i4);

}

}

//结果为:true true

至于为什么是这个结果,同样地,看了Boolean类的源码也会一目了然。下面是Boolean的valueOf方法的具体实现:

public static Boolean valueOf(boolean b) {

return (b ? TRUE : FALSE);

}

public class H {

public static void main(String[] args) {

Integer m=10;

int n=10;

System.out.println(m==n);

}

}

//结果为:true

java中如何安装.jar包

JAVA为我们提供了大量基础 jar 包,但在实际开发中,经常还需要引入第三方 jar 包,比如做 HTTP 操作时的 HttpClient jar 包, 那如何将第三方 jar 包引入到自己的工程中呢?

步骤一 : 在工程上右键 "New"--"Folder" 新建一个名称为 lib 的文件夹,并将第三方 jar 包全部拷贝到这个目录下!

步骤二 : 在工程上右键 "Build Path"--"Configure Build Path...";

1 在新打开的窗轮磨口中点击右侧按钮 "Add Library", 打开 "Add Library" 窗口;

2 在弹出窗口中选择 "User Library", 点击 "Next" ;

3 在弹出窗口中继续点击 "User Libraries..." ;

4 在弹唯桐键出窗口中继续点击 "New..." ;

5 在弹出窗口中输入 User Library 的名称 "HttpClientJars", 点击 "OK";

6 在回到的窗口中,选择刚才创建的项 “HttpClientJars”,点击 "Add JARs" ;

7 在弹出的窗口中,找到我们的工程,选中我们拷贝到 lib 目录下的所有 jar 文件,点击 "OK" ;

8 回到 “Add Library”窗口,在 User Library 列表中选择刚刚创建的 "HttpClientJars", 点击 "Finish" ;

9 关闭所有窗口,添加完毕。

步骤四 : 总结

这是添加第三方 jar 包通用的方法,根据这个方法,我们可以把需要的所有第指巧三方 jar 包以一种很干净整洁的方式添加到工程中!

关于经验中涉及的 HttpClient jar 包


分享名称:java装包拆包代码 java 拆箱装箱
分享链接:http://jkwzsj.com/article/ddppooj.html

其他资讯