java支持的数据类型有哪些_Java支持的数据类型有哪些?什么时候自动装拆箱?...

java中的8种基本数据类型:boolean byte char short int float double long

自动拆装箱的问题引入:

由于在一开始学习java的时候,”万物皆对象“这种面向对象的看问题方式,时刻围绕在脑海中。因为静态的变量和基本数据类型不属于对象,但是由8种基本数据类型的自动装拆箱解决了基本数据类型不是对象。

在jdk1.5中引入了自动拆装箱的新特性,在jdk1.5之前,我们想要使用integer类中的方法,我们先要把int变量变成integer类型,可以通过new Integer(intNumber) 或者调用Integer.valueOf(intNumber)方法

自动装拆箱何时发生?

1、在调用方法时把基本数据类型作为参数,但是参数的类型是基本数据类型的包装类时。

在学习过javaSe基础之后,我们知道通过使用集合框架ArrayList或者Map来添加元素的时候,添加的是Object对象,在这里引入ArrayList.add()的源码:

/**

* Appends the specified element to the end of this list.

*

* @param e element to be appended to this list

* @return true (as specified by {@link Collection#add})

*/

public boolean add(E e) {

ensureCapacity(size + 1); // Increments modCount!!

elementData[size++] = e;

return true;

}

1

2

3

4

5

6

7

8

9

10

11

对于源码的解读:首先我们来看看参数中的(E e),为什么是E ?而不是Object?因为E代表的是元素(集合中存储的是元素),我们平时在泛型中可以看到 > ,T 代表的是Type 类,再比如键值对中的Map,K 表示的是Key,V 表示的是Value。E K V 等泛型在使用该参数之前就已经限定好了类型,如果赋值给Object的话,就不用再进行强制类型转换了。

首先把数组的长度+1,这个操作会导致modCount加一,这个变量的作用就是记录当前数组被操作的次数,然后直接把参数传进来的对象赋值给上一次长度位置的元素。返回true表示添加成功

当我们调用ArrayList.add()方法的时候,可以直接调用

ArrayList arrayList = new ArrayList();

arrayList.add(10);

1

2

我们反编译这段代码:

public class AutoboxingTest

{

public AutoboxingTest()

{

}

public static void main(String args[])

{

ArrayList arrayList = new ArrayList();

arrayList.add(Integer.valueOf(100));

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

可以看到,编译器在编译的时候,检测到arrayList.add()需要的是Integer对象,所以把int类型自动装箱成Integer类型。

2、 给基本数据类型的包装类赋值为基本数据类型的时候。

我们还是以Integer和int类型的变量作为例子:

public class AutoboxingTest2 {

public static void main(String[] args) {

Integer integer = 10;

}

}

1

2

3

4

5

6

7

继续反编译例子:

public class AutoboxingTest2

{

public AutoboxingTest2()

{

}

public static void main(String args[])

{

Integer integer = Integer.valueOf(10);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

什么时候自动装箱不起作用?

当我们要调用的方法中存在重载的时候,即基本类型数据作为唯一参数的方法与该基本类型包装类作为唯一参数的方法重载,这时候自动装箱不起作用。

例子:

public class InvalidateAutoboxing {

public void print(int num) {

System.out.println("i am int !");

}

public void print(Integer num) {

System.out.println("i am integer!");

}

}

public class InvalidateAutoboxingTest {

public static void main(String[] args) {

InvalidateAutoboxing invalidateAutoboxing = new InvalidateAutoboxing();

invalidateAutoboxing.print(5);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

运行结果:

这里写图片描述

使用自动装箱拆箱需要注意的地方:

1、循环与自动装箱拆箱

public class CirculateAndAutoboxingAndAutounboxing {

public static void main(String[] args) {

Integer sum = 0;

for (int i = 0; i < 200; i++) {

sum += i;

}

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

反编译:

public class CirculateAndAutoboxingAndAutounboxing

{

public CirculateAndAutoboxingAndAutounboxing()

{

}

public static void main(String args[])

{

Integer sum = Integer.valueOf(0);

for(int i = 0; i < 200; i++)

sum = Integer.valueOf(sum.intValue() + i);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

反编译代码解读:由于sum是Integer类型,但是sum+=i 需要sum先自动拆箱成int类型(调用intValue()方法),进行相加之后,再自动装箱成Integer类型把结果赋给sum。

Integer.valueOf源码解析:

/**

* Returns a Integer instance representing the specified

* int value.

* If a new Integer instance is not required, this method

* should generally be used in preference to the constructor

* Integer(int), as this method is likely to yield

* significantly better space and time performance by caching

* frequently requested values.

*

* @param i an int value.

* @return a Integer instance representing i.

* @since 1.5

*/

public static Integer valueOf(int i) {

final int offset = 128;

if (i >= -128 && i <= 127) { // must cache

return IntegerCache.cache[i + offset];

}

return new Integer(i);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

首先我们在源码说明中看到了该构造器缓存经常使用的数据以减少内存的使用和提高效率,Integer把缓冲区的上限脚标设置成128,如果传进来的数据i在-128~127之中,直接返回缓冲区中的IntegerCache.cache[i + 128] 位中的元素

IntegerCache的源码解读:

private static class IntegerCache {

private IntegerCache(){}

static final Integer cache[] = new Integer[-(-128) + 127 + 1];

static {

for(int i = 0; i < cache.length; i++)

cache[i] = new Integer(i - 128);

}

}

1

2

3

4

5

6

7

8

9

10

IntegerCache是Integer的内部类,并且内部数组的上限为256元素,在这个内部类中使用了静态代码块(在类加载的时只执行一次),把-128~127都缓存在数组中。所以以后调用的时候就可以直接返回Integer对象,而不用return new Integer(i); Integer Short Long的缓冲数组是一样的,但是Character的范围为0~127,Double和Float没有缓冲数组

话又说回来,刚刚我们在分析循环与自动装拆箱的使用需要注意:当参与的数值不在缓存的范围内,会产生大量的对象,这样会产生很多垃圾对象,增加GC的工作压力。

2、自动装拆箱与三元运算符造成的空指针异常(NPE)

public class AutounboxingWithConditionalOperator {

public static void main(String[] args) {

HashMap hashMap = new HashMap();

Boolean b = (hashMap != null ? hashMap.get("test") : false);

}

}

1

2

3

4

5

6

7

8

9

10

运行:

这里写图片描述

发生了空指针异常

如果在Map中添加了test这条数据:

public class AutounboxingWithConditionalOperator {

public static void main(String[] args) {

HashMap hashMap = new HashMap();

hashMap.put("test", true);

Boolean b = (hashMap != null ? hashMap.get("test") : false);

System.out.println(b);

}

}

1

2

3

4

5

6

7

8

9

10

运行:

这里写图片描述

我们再反编译刚刚NPE异常的代码:

public class AutounboxingWithConditionalOperator

{

public AutounboxingWithConditionalOperator()

{

}

public static void main(String args[])

{

HashMap hashMap = new HashMap();

Boolean b = Boolean.valueOf(hashMap == null ? false : ((Boolean)hashMap.get("test")).booleanValue());

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

下面是hashMap.get(key)方法的说明:

Returns the value to which the specified key is mapped,

*or null if this map contains no mapping for the key.

由上面可以看出,由于Map.get(key)方法,如果没有指定的数据,返回的是null。

再由于三元运算符有如下定义:

The type of a conditional expression is determined as follows:

1、If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression.

2、If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.

3、If one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type.

译文:

三元运算符的类型由以下情况决定:

1、如果第二和第三个操作结果拥有同样类型(这个类型可能为null),那么这个类型就是该三元运算符的结果类型

2、如果第二个操作和第三个操作结果其中一个的结果类型为基本数据类型,另外一个操作结果为可以装箱转换成与前面一种类型一致的包装类,那么这个三元运算符的运算结果类型为基本数据类型,即把包装类拆装。

3、如果在第二、三个操作结果中,有一个为null类型,另外一个为引用类型,那么这个三元运算符的表达式为引用类型。

综上所述,对于上面出现的情况,对于一个操作结果为基本类型,另外一个为包装类型的三元运算符表达式来说,为了避免NEP的产生,可以通过把它们变成同样类型(参考三元运算符定义的第一条)。

参考资料:

Conditional Operator ? :

Boxing Conversion

The Java™ Tutorials about Autoboxing and Unboxing

What is Autoboxing and Unboxing in Java

Java中的自动装箱与拆箱

要裝箱還是拆封

4.2 自動裝箱、拆箱

Java 自动装箱和拆箱

Java泛型中K T V E ? object等的含义

自动拆箱导致空指针异常

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/347756.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java面向对象(4)--封装和隐藏

Java中通过将数据声明为私有的(private)&#xff0c;再提供公共的&#xff08;public&#xff09;方法:获取getXxx()和设置setXxx()实现对该属性的操作&#xff0c;以实现下述目的&#xff1a; ①隐藏一个类中不需要对外提供的实现细节。 ②使用者只能通过事先定制好的方法来访…

跑来跑去:假人与AWS Lambda的第一次接触

一切始于埃及人在一个木框上滑动几块大理石以简单的算术使其大脑放松。 或许是希腊人发明了Antikythera机制来追踪行星的运动至每千年2度的精度 。 无论哪种方式&#xff0c;计算都已经走了很长一段路&#xff1a;查尔斯巴贝奇的分析引擎 &#xff0c;艾伦图灵的Enigma-breaker…

(2.1)HarmonyOS鸿蒙Ability创建,XML和Java页面布局UI

鸿蒙UI中&#xff0c;提供了两种编写布局的方式&#xff1a; ①在XML中声明UI布局 ②在Ability代码中直接通过Java创建布局 这两种方式创建出的布局没有本质差别&#xff0c;但是XML方式较为方便简单。 在XML文件中布局 与HTMLCSS的前端布局类似&#xff0c;通过使用不同类型的…

cstring越界_CString和char*的转换

方法1、const char*转换CString str;const char *p(const char*)str;const char *表示你对字符串只读&#xff0c;所以这时候可以直接获取。方法2、使用强制类型转换如需要对字符串写权限&#xff0c;则&#xff1a;CString str;char *p (char *)(const char *)str;方法3、使用…

使用Azure Blob存储托管Maven工件

如果您使用Microsoft Azure并且将Java用于项目&#xff0c;则Azure Blob存储是托管团队工件的理想场所。 它很容易设置&#xff0c;而且很便宜。 如果您对它们的功能不特别感兴趣&#xff0c;那么它比设置现有存储库选项&#xff08;jfrog&#xff0c;nexus&#xff0c;archiv…

(2.2)HarmonyOS鸿蒙页面跳转

本文页面跳转基于《Ability创建子页面布局》所存在的两个页面MainAbility和SecondAbility。 在MainAbilitySlice中进行代码编写 package com.example.myapplication.slice;import com.example.myapplication.ResourceTable; import ohos.aafwk.ability.AbilitySlice; import o…

java 将换行代替_Java批量将文件中的段落替换成空格,根据指定分隔符换行(SQL示例)...

我的需求是SQL文件中有成千的类似数据&#xff0c;我要将它们进行转换格式&#xff0c;如下图第一步&#xff1a;将字符段楼替换&#xff0c;使用word排版把数据拷贝到word中&#xff0c;使用特殊字符替换点击全部替换&#xff0c;替换之后如下图&#xff0c;这时候它是一串很长…

wicket_Wicket模型的干净方法

wicketApache Wicket Web框架的核心概念之一是模型和IModel作为其编程接口。 Wicket组件严重依赖模型&#xff0c;这使它们成为体系结构的重要组成部分。 Apache Wicket是一个有状态框架&#xff0c;将页面及其组件存储到通常位于HTTP会话中的页面存储中。 组件根据模型的内容创…

计算机二级web题目(8.2)--基本操作题2

前些天发现了一个巨牛的人工智能学习电子书&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;无广告&#xff0c;忍不住分享一下给大家。&#xff08;点击跳转人工智能学习资料&#xff09; 1.在考生文件夹下的Web1目录中&#xff0c;存有1.htm文件&#xff0c;该文件不完…

java的选项板_CAD工具选项板的介绍以及新建方法

CAD中的工具选项板是【工具选项板】窗口中选项卡形式的区域&#xff0c;不但能提供组织、共享和放置块及填充图案的很有效的方法&#xff0c;还能够包含由第三方开发人员提供的自定义工具。【工具选项板】窗口包括注释、建筑、机械、电力、图案填充和土木工程等选项板。当需要向…

摆脱“空”检查的盛宴:使用JSON Patch正确执行PATCH

今天&#xff0c;我们将就REST&#xff08;ful&#xff09;服务和API进行一次对话&#xff0c;更准确地说&#xff0c;围绕许多经验丰富的开发人员正在努力解决的一个独特主题。 为了使事情更直观&#xff0c;我们将讨论Web API&#xff0c;其中REST&#xff08;ful&#xff09…

Java面向对象(5)--类的成员构造器(构造方法)

创建对象&#xff1b;给对象进行初始化。 ①隐式无参构造器&#xff08;没有创建时&#xff0c;系统默认提供的&#xff09; ②显式定义一个或多个构造器&#xff08;无参、有参&#xff09; 基本格式 修饰符 类名 (参数列表) {初始化语句&#xff1b; }特征 ①它具有与类相…

java单链表 提供增删改查_java实现单链表增删改查的实例代码详解

package 数据结构算法.链表;/**定义节点* 链表由节点构成*/public class node {private e e; //数据dataprivate node next; //指向下一个节点public node() {}public node(e e) {this.e e;}public node getnext() {return next;}public void setnext(node next) {this.next …

Java面向对象(6)--this关键字使用

this可理解为:当前对象或当前正在创建的对象 ①在类的方法中&#xff0c; 我们可以使用"this.属性"或"this.方法"的方式&#xff0c;调用当前对象属性或方法。通常情况下&#xff0c;我们都选择省略"this."。特殊情况下&#xff0c;如果方法的形…

spring 4.3.x_如何在Spring 3.x中使用事件

spring 4.3.x创建松耦合应用程序的概念和技术很多&#xff0c;Event是其中之一。 事件可以消除代码中的许多依赖关系。 有时没有事件&#xff0c;很难实施SRP *。 Java中的Observable接口可以帮助我们实现事件&#xff08;通过Observer Pattern&#xff09;。 但是&#xff0c…

java接口安全怎么处理_Restful API 接口安全性设计

1.API接口设计规范2.安全性设计a.白名单限制仅接受特定系统的请求响应&#xff0c;调用方的IP地址需要在本系统中报备&#xff0c;否则无法调用b.合法身份合法性验证Basic Authentication :这种方式是直接将用户名和密码放到Header中&#xff0c;使用 Authorization: Basic Zm9…

使用Spring开发Java RESTful Web服务的7个理由

REST现在已成为开发Web服务的标准方法&#xff0c;涉及Java时&#xff0c;可以使用许多框架和库&#xff0c;例如JAX-RS&#xff0c;Restlet&#xff0c;Jersey&#xff0c;RESTEasy&#xff0c;Apache CFX等&#xff0c;但是我鼓励Java开发人员使用Spring框架来开发Java。开发…

Java面向对象(7)--package和import关键字

package关键字 ①为了更好的实现项目中类的管理&#xff0c;提供包的概念 ②使用package声明类或接口所属的包&#xff0c;声明在源文件的首行 ③包&#xff0c;属于标识符&#xff0c;遵循标识符的命名规则、规范( xxxyyyzzz) ④每"."一次&#xff0c;就代表一层文…

java圆形排列_位图排序java版

1、《编程珠玑》第一章第一题就相当的精彩&#xff0c;做个笔记。题目如下&#xff1a;输入: 一个包含n个正整数的文件&#xff0c;每个正整数小于n,n等于10的7次方(一千万)。并且文件内的正整数没有重复和关联数据。输出: 输入整数的升序排列约束&#xff1a; 限制在1M左右…

(3.1)HarmonyOS鸿蒙单击事件4种写法

第二种和第四种常用 实现步骤: 1.通过id找到组件。 2.给需要的组件设置单击事件。 3.实现ClickedListener接口。 4.重写onClicked方法。 第一种&#xff0c;自定义实现类&#xff08;在当前类外面写实现类&#xff09; ①MainAbilitySlice.java文件 package com.example.yem…