在我看来,java里面里面除了原生类型不是对象,其他的都是对象。但java是面向对象的语言,很多地方还要要操作对象,所以java会自动把原生类型转为对应的包装类型。这个过程叫自动装箱。有装箱就有拆箱,就是包装的对象转换为原生类型。

java里面一共有8种原生数据类型。

类型 占字节大小  
boolean ?  
byte 8位有符号的二进制补码整数  
char 单个16 位Unicode 字符  
short 16位有符号的补码整数  
int 32位有符号的补码整数  
float 单精度 32 位 IEEE 754 浮点数  
long 64位有符号的补码整数  
double 单精度 64 位 IEEE 754 浮点数  

自然对应自动装箱后就是Boolean, Byte, Character, Short, Integer, Float, Long, Double。我们可以用包装类来了解一下类型的细节。

大家是否觉得奇怪,boolean的大小是?,是未确定的。(很多人是以为1位)。以下是网上搜索的定义

使用此数据作为简单标记来跟踪真/假条件。这种数据类型代表一个比特的信息,但它的“大小”没有明确界定。

下面我们来代码来答应相关的细节。

package cn.xiaowenjie;

public class BasicTypeDemo
{
public static void main(String[] args)
{
System.out.println("Boolean:没有size属性");
System.out.println("Byte: size:" + Byte.SIZE + ", Max:" + Byte.MAX_VALUE + ", Min:" + Byte.MIN_VALUE);
System.out.println("Character: size:" + Character.SIZE + ", Max:" + Character.MAX_VALUE + ", Min:"
+ Character.MIN_VALUE);
System.out.println("Short: size:" + Short.SIZE + ", Max:" + Short.MAX_VALUE + ", Min:" + Short.MIN_VALUE);
System.out.println("Integer: size:" + Integer.SIZE + ", Max:" + Integer.MAX_VALUE + ", Min:"
+ Integer.MIN_VALUE);
System.out.println("Float: size:" + Float.SIZE + ", Max:" + Float.MAX_VALUE + ", Min:" + Float.MIN_VALUE);
System.out.println("Long: size:" + Long.SIZE + ", Max:" + Long.MAX_VALUE + ", Min:" + Long.MIN_VALUE);
System.out.println("Double: size:" + Double.SIZE + ", Max:" + Double.MAX_VALUE + ", Min:" + Double.MIN_VALUE);
} }

输出结果:

Boolean:没有size属性
Byte: size:8, Max:127, Min:-128
Character: size:16, Max:【不可见】, Min:【不可见】
Short: size:16, Max:32767, Min:-32768
Integer: size:32, Max:2147483647, Min:-2147483648
Float: size:32, Max:3.4028235E38, Min:1.4E-45
Long: size:64, Max:9223372036854775807, Min:-9223372036854775808
Double: size:64, Max:1.7976931348623157E308, Min:4.9E-324

有几点要注意

  1. Boolean类型没有size属性,所以说大小是未定的。
  2. JAVA里面的类型都是带符号的,而且是所有平台都是一样的长度。
  3. Character类型的最大最小值的定义是
    public static final char   MIN_VALUE = '\u0000';
public static final char MAX_VALUE = '\uffff';

所以char类型是可以指定中文的,如

        char c1 = 'a';
char c2 = '我';

还有一点疑问:为什么Integer和Float都是32位的,float的最大值比int的最大值大这么多?3.4028235E38是科学计数法,远远大于2147483647。答案就是一个是32位
有符号的补码整数,一个是32 位 的
单精度
 
IEEE 754 浮点数。但我不知道这有什么区别,烦知道的大拿不吝赐教。这2个东西有什么不一样,内存里面存放是如何的。

原生类型的特性(优势):

  1. 存放位置是放在栈里面,不需要用到堆,存储比较快。
  2. 不可变,包括包装类都是不可变的(全部是final)。

不可变的意思是说内存里面的值一旦被设置后就不会改变,如果要改变就会另外开辟一个位置存放新的值,但旧的值还在。如

 int i1 = 1;
int i2 = 1;
i2 = 2;

第1,2行里面,i1和i2是一样的值,他们实际是指向同一个内存空间(虽然2个变量,实际一个空间),第2行i2修改成其他值的时候,i2就指向了一个新的内存空间,里面是2。

关于这个结论,不知道方法有没有可以通过代码来验证呢?知道的兄弟在评论里面说一下。

string类型的内存读写机制和这个一样。

BigDecimal:

float和double不能存在精准的浮点数值,如果需要用到小数,可以使用BigDecimal。

            float f1 = 0.999999999999f;
float f2 = 0.000000000001f; System.out.println((1.0f - f1) == f2);
System.out.println((f1 + f2) == 1.0f);

输出第一个为false,第2个为true。具体原因没有深究。(这个例子不知道恰不恰当)


使用BigDecimal能精确运算浮点数。但使用构造函数需要小心,要使用字符串类型的构造函数。

        BigDecimal bd1 = new BigDecimal("0.12345");
BigDecimal bd2 = new BigDecimal(0.12345); System.out.println(bd1);
System.out.println(bd2);

输出

0.12345
0.123450000000000004174438572590588591992855072021484375


java没有运算符重载,所以使用BigDecimal对象后,加减乘除就要调用对象的方法啦(add,subtract,multiply,divide),还有其他的方法自己查看提示即可。


数字进制:

一般使用都是10机制,8进制的是0开头,16进制是0x开头,这个和javascript是一样的。有时候不小心容易出错。如 0100 和 100 就是不一样的值。

自动拆箱引发的空指针:

这是个工作上遇到的例子,简单写个样例代码。(不考虑规范和合理性。)

public class NullPointerDemo
{ public static void main(String[] args)
{
HashMap map = new HashMap(); int count = getCount(map.keySet()); // 这行报空指针错误
System.out.println(count);
} private static Integer getCount(Collection keys)
{
if (keys == null || keys.isEmpty())
{
return null;
} return keys.size();
} }

运行报空指针错误。在这行

int count = getCount(map.keySet());

根据经验,马上是断定map为空,才会抛出空指针,但实际上不是。反编译一看即知道缘由。反编译后,上面这行对应的代码是

int count = getCount(map.keySet()).intValue();

可见这行跑空指针可能map为空,也可能是getCount函数为空。

注意点:

由于原生类型不是对象,在需要使用对象的地方虚拟机会自动装箱成对应的对象,代码上看上去很正常,但实际上是2个东西。所以有些系统间的调用接口,如果参数定义成原生类型,调用会失败。

如之前在windchill里面做的一个远程调用的例子,方法定义里面是int,远程调用的时候就会失败了。远程调用里面会要输入参数的类型(class),而原生类型不是对象,没有类型,只有装箱后的类型,所以导致错误。

以上的内容都是根据个人的理解总结出来的,肯定有不少纰漏错误,请大家看到的时候一定要不吝指出啊!谢谢啦!

java系列之 原生数据类型的更多相关文章

  1. Java中的原生数据类型

    Java中的原生数据类型(Primitive DataType)共有8种: 1)整型:     使用int表示(32位).2)字节型: 使用byte表示(从-128到127之间的256个整数).3)短 ...

  2. JAVA 1.3 (原生数据类型 Primitive Data Type)续

    1. 原生数据类型一共有4类8种 >> 整数类型 int表示一个int代表32位 2^32(-2147483648 - 2147483647) >> 字符类型 byte 表示一 ...

  3. JAVA 1.2(原生数据类型 Primitive Data Type)

    1. Java的数据类型分为2类 >> 原生数据类型(primitive data type) >> 引用数据类型(reference data type) 3. 常量和变量 ...

  4. Java系列笔记(3) - Java 内存区域和GC机制

    目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...

  5. Java系列笔记(1) - Java 类加载与初始化

    目录 类加载器 动态加载 链接 初始化 示例 类加载器 在了解Java的机制之前,需要先了解类在JVM(Java虚拟机)中是如何加载的,这对后面理解java其它机制将有重要作用. 每个类编译后产生一个 ...

  6. Java系列笔记(6) - 并发(上)

    目录 1,基本概念 2,volatile 3,atom 4,ThreadLocal 5,CountDownLatch和CyclicBarrier 6,信号量 7,Condition 8,Exchang ...

  7. 【转载】Java系列笔记(1) - Java 类加载与初始化

    Java系列笔记(1) - Java 类加载与初始化 原文地址:http://www.cnblogs.com/zhguang/p/3154584.html 目录 类加载器 动态加载 链接 初始化 示例 ...

  8. 【转载】Java系列笔记(3) - Java 内存区域和GC机制

    Java系列笔记(3) - Java 内存区域和GC机制 转载:原文地址http://www.cnblogs.com/zhguang/p/3257367.html 目录 Java垃圾回收概况 Java ...

  9. Java学习之基本数据类型和引用数据类型区别

    JAVA中分为基本数据类型和引用数据类型区别一.基本数据类型: byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0 short:短整型,在内存 ...

随机推荐

  1. 洛谷 P1056 排座椅 桶排序

    桶排序大法好! 每次一看到这种范围小的题,本萌新就想用桶排. 因为题目中的m,n都小于1000,我们就可以定义两个1000的数组,表示每一行或每一列可以隔开几对讲话的童鞋. 然后再定义两个1000的数 ...

  2. Python 入门基础11 --函数基础4 迭代器、生成器、枚举类型

    今日目录: 1.迭代器 2.可迭代对象 3.迭代器对象 4.for循环迭代器 5.生成器 6.枚举对象 一.迭代器: 循环反馈的容器(集合类型) 每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的 ...

  3. mount过程分析之一(基于3.16.3内核)【转】

    转自:https://blog.csdn.net/zr_lang/article/details/39963253 一直想写有些关于文件系统的博文,但是由于近一年来实在太忙,所以没有时间写.前几日赶上 ...

  4. df -h执行卡住不动问题解决【转】

    昨天生产环境报日志写不进去了,因此 登陆线上环境后,习惯用df -h命令查看空间使用情况,结果发现该命令执行半天也没有返回. 因此使用mount命令查看该机器上的目录: [conversant@swi ...

  5. hashlib和hmac

    hashlib hashlib模块用于加密相关的操作,代替了md5和sha模块,主要提供SHA1,SHA224,SHA256,SHA384,SHA512,MD5算法. #!/usr/bin/env p ...

  6. PowerMockRunner和ActiveObjectsJUnitRunner

    Jira的二次开发,需要作单元测试. 测试跟数据库连接的类,比如service类,需要在类上加@RunWith(ActiveObjectsJUnitRunner.class). 有时需要搭配mocki ...

  7. SqlServer中查看索引的使用情况

    --查看数据库索引的使用情况 select db_name(database_id) as N'TOPK_TO_DEV', --库名 object_name(a.object_id) as N'Top ...

  8. redis 持久化的两种方式

    一:快照模式 或许在用Redis之初的时候,就听说过redis有两种持久化模式,第一种是SNAPSHOTTING模式,还是一种是AOF模式,而且在实战场景下用的最多的 莫过于SNAPSHOTTING模 ...

  9. 一个ScheduledExecutorService启动的Java线程无故挂掉引发的思考

    2018年12月12日18:44:53 一个ScheduledExecutorService启动的Java线程无故挂掉引发的思考 案件现场 不久前,在开发改造公司一个端到端监控日志系统的时候,出现了一 ...

  10. 利用angular指令监听ng-repeat渲染完成后执行脚本

    业务中有时需要在异步获取数据并用ng-repeat遍历渲染完页面后执行某个操作,angular本身并没有提供监听ng-repeat渲染完成的指令,所以需要自己动手写.有经验的同学都应该知道,在ng-r ...