专业编程基础技术教程

网站首页 > 基础教程 正文

三石说:java基础之 基本数类型

ccvgpt 2024-11-18 09:21:54 基础教程 7 ℃

对于各种语言,我们想做数据的计算,那么我们是不是需要定义出不同的数据类型,然后让程序来做运算,所以java也不例外,下面列举了java基本数据类型,和所对应的包装类。今天我们将看下具体的讲解。

java八大基本数据类型:

  • 布尔型:Boolean
  • 整数型:byte1 short 2.int 4.long8
  • 字符型:char
  • 浮点型:float double

类型包装类字节位数byteByte8位 -128-127booleanBoolean默认falseshortShort16位-32768- 32767charCharacter16位,存储Unicode码intInteger32位longLong64位floatFloat32位doubleDouble64位

三石说:java基础之 基本数类型

包装类

既然java是面向对象的语言,那么我们使用基本数据类型是不是能满足我们日常的操作,我们常常是用对象进行操作的。 对于Character和Boolean是直接继承的Object的其他的包装类型都是继承与Number子类的。

对于包装类与基本数据类型我们常使用的有两个方法

// 装箱

xxx.ValueOf(); 参数为基本数据类型,返回包装类对象。参数为string的可以返回包装类对象,但是必须保证,字符串是符合的与返回的对象

// 拆箱

parseXXX():Charcater没有这个方法。这个是将包装类转为基本数据类型

自动类型转换

整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算。

转换从低级到高级。

低  ------------------------------------>  高

byte,short,char—> int —> long—> float —> double 

数据类型转换必须满足如下规则:

  1. 不能对boolean类型进行类型转换。
  2. 不能把对象类型转换成不相关类的对象。
  3. 在把容量大的类型转换为容量小的类型时必须使用强制类型转换。
  4. 转换过程中可能导致溢出或损失精度,例如:
int i =128;   
byte b = (byte)i;
因为 byte 类型是 8 位,最大值为127,所以当 int 强制转换为 byte 类型时,值 128 时候就会导致溢出。
  1. 浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入,例如:
(int)23.7 == 23;        
(int)-45.89f == -45

自动类型转换 必须满足转换前的数据类型的位数要低于转换后的数据类型,例如: short数据类型的位数为16位,就可以自动转换位数为32的int类型,同样float数据类型的位数为32,可以自动转换为64位的double类型。

实例
public class ZiDongLeiZhuan{
        public static void main(String[] args){
            char c1='a';//定义一个char类型
            int i1 = c1;//char自动类型转换为int
            System.out.println("char自动类型转换为int后的值等于"+i1);
            char c2 = 'A';//定义一个char类型
            int i2 = c2+1;//char 类型和 int 类型计算
            System.out.println("char类型和int计算后的值等于"+i2);
        }
}
运行结果为:

char自动类型转换为int后的值等于97
char类型和int计算后的值等于66
解析:c1 的值为字符 a ,查 ASCII 码表可知对应的 int 类型值为 97, A 对应值为 65,所以 i2=65+1=66。

强制类型转换

  1. 条件是转换的数据类型必须是兼容的。
  2. 格式:(type)value type是要强制类型转换后的数据类型 实例:
实例
public class QiangZhiZhuanHuan{
    public static void main(String[] args){
        int i1 = 123;
        byte b = (byte)i1;//强制类型转换为byte
        System.out.println("int强制类型转换为byte后的值等于"+b);
    }
}
运行结果:

int强制类型转换为byte后的值等于123

隐含强制类型转换

  1. 整数的默认类型是 int。
  2. 浮点型不存在这种情况,因为在定义 float 类型时必须在数字后面跟上 F 或者 f。

常量池

常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括关于类、方法、接口中的常量,也包括字符串直接量。

常量池大体可以分为:静态常量池,运行时常量池。

静态常量池 存在于class文件中,比如经常使用的javap -verbose中,常量池总是在最前面把?

运行时常量池呢,就是在class文件被加载进了内存之后,常量池保存在了方法区中,通常说的常量池 是运行时常量池。所以呢,讨论的都是运行时常量池

常量池现在了解到的有字符串常量池

String s1 = "abc";
在字符串常量池中查找是否有"abc"对象, 如果没有则创建"abc"再将s1指向"abc"; 
如果有就直接将s1指向"abc";
   String s2 = new String("efg");
直接在堆中创建"efg"对象, 然后将栈中的s2指向"efg"
例子1:
String s1 = "abc";
String s2 = "abc";//将s1存放的地址赋值给s2, 则s2也指向了"abc"对象
System.out.println(s1 == s2);//true
String s3 = new String("abc");
String s4 = new String("abc");
System.out.println(s3 == s4);//false

原理:类似于基本数据类型, 只是数据存放的位置不一样, 基本数据类型存放在栈; 
    字符串变量存放在栈, 对象存放在堆.

缓存池

缓存池就是虚拟机预先缓存的值,便于操作,可以理解为计算机缓冲技术类似,(其实也是存在常量池冲)

java中基本类型的包装类的大部分都实现了常量池技术,这些类是Byte,Short,Integer,Long,Character,Boolean,另外两种浮点数类型的包装类则没有实现。另外Byte,Short,Integer,Long,Character这5种整型的包装类也只是在对应值小于等于127时才可使用常量池,也即对象不负责创建和管理大于127的这些类的对象 基本类型对应的缓冲池如下:

  • boolean values true and false
  • all byte values
  • short values between -128 and 127
  • int values between -128 and 127
  • char in the range \u0000 to \u007F

在使用这些基本类型对应的包装类型时,如果该数值范围在缓冲池范围内,就可以直接使用缓冲池中的对象。

在 jdk 1.8 所有的数值类缓冲池中,Integer 的缓冲池 IntegerCache 很特殊,这个缓冲池的下界是 - 128,上界默认是 127,但是这个上界是可调的,在启动 jvm 的时候,通过 -XX:AutoBoxCacheMax= 来指定这个缓冲池的大小,该选项在 JVM 初始化的时候会设定一个名为 java.lang.IntegerCache.high 系统属性,然后 IntegerCache 初始化的时候就会读取该系统属性来决定上界。

Integer i = 1;

等号右边的数若在[-128,127], 则先将其装箱成包装类,然后存放在Integer缓冲池中 (看源码可以知道, 其实就是存放在Integer类型的数组中). 先查看缓冲池中是否有该Integer对象, 若有则将变量i指向它; 若没有则在缓冲池中创建Integer对象,将变量i指向它.

Integer j = 200;

因为右边的数不在[-128,127], 直接在堆内存中创建Integer对象, 将变量j指向它.

看下源码:

 /**
 * 缓存以支持JLS要求的-128到127(含)之间的值的自动装箱的对象标识语义。 首次使用时会初始化缓存。
 * 缓存的大小可以由-XX:AutoBoxCacheMax=<size>选项控制。 
 * 在VM初始化期间,可以在sun.misc.VM类的私有系统属性中设置并保存java.lang.Integer.IntegerCache.high属性
 */
 private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

关于常量池和缓冲池了解不是很深入,待我看JVM时我将回过头来进行重新补充。

基本类型常见的面试题:

Q&A:什么是自动装箱与拆箱?

自动装箱就是java编译器在基本数据类型和对应的对象包装类型之间做一个转化,比如int转为Integer,double转为Double.反之为自动拆箱。

Q&A:String是基本的数据类型吗?

String不是节本的数据类型,是final不可修改的类,为了提高效率可以使用StringBuffer类。

Q&A:int 和integer有什么区别?

int是基本类型,integer是包装类型。

integer必须实例化后才能使用,而int变量不需要。

integer默认为null,而int默认为0;

integer实际是对象的引用,当new出一个integer时实际上是生成一个指针指向此对象,而int则是直接存储数据值。

Q&A:以下结果是什么?

Integer a= new Integer(3);
Integer b= 3; // 将3 自动装箱为Integer类型
int c=3;
a==b  // false 两个引用没有引用统一对象。
a==c // true a 自动 拆箱为int 再和c 比较。
两个非new生成的integer对象,进行比较时如果两个变量值的区间在-128~127之间则比较为 true,如果不在此区间则为false;
Integer a=100;  => Integer a = Integer.valueOf(100);
Integer b=100;
a==b // true;
Integer a=128;
Integer b=128;
a== b // false;
对于valueOf方法在Integer类中会有一个cache判断:

Q&A short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 +=1;有什么错?

1) 对于 shorts1=1;s1=s1+1 来说,在s1+1 运算时会自动提升表达式的类型为 int, 那么将int赋予给 short类型的变量 s1会出现类型转换错误。 2) 对于 short s1=1;s1+=1 来说 +=是java 语言规定的运算符,java 编译器会对它 进行特殊处理,因此可以正确编译。

ok 这就是我要分享的java基本数据类型


最近发表
标签列表