【Java学习笔记】基础知识数据类型、String、运算


一、数据类型

基本类型

整型:

  • byte/8 bit
  • short/16 bit
  • int/32 bit
  • long/64 bit

浮点型:

  • float/32 bit
  • double/64 bit

字符型:

  • char/16

布尔值:

  • boolean/

boolean 只有两个值:true、false,用来判定逻辑条件。整型值和布尔值之间不能进行相互转换。可以使用 1 bit 来存储,但是具体大小没有明确规定。JVM 会在编译时期将 boolean 类型的数据转换为 int,使用 1 来表示 true,0 表示 false。JVM 支持 boolean 数组,但是是通过读写 byte 数组来实现的。

在Java中,所有的数值类型所占据的字节数量是不变的,其不会随着机器硬件的变化而改变,而且Java中没有任何无符号类型(unsigned)。

JVM简介

JVM(Java Virtual Machine),是可运行 Java 代码的假想计算机 ,包括一套字节码指令集、一组寄存器、一个栈、 一个垃圾回收,堆和 一个存储方法域。JVM 是运行在操作系统之上的,它与硬件没有直接的交互。
在这里插入图片描述
我们都知道 Java 源文件,通过编译器,能够生产相应的 .Class 文件,也就是字节码文件, 而字节码文件又通过 Java 虚拟机中的解释器,编译成特定机器上的机器码 。
也就是如下:

​ ① Java 源文件 --> 编译器 --> 字节码文件

​ ② 字节码文件 --> JVM --> 机器码

每一种平台的解释器是不同的,但是实现的虚拟机是相同的,这也就是 Java 为什么能够跨平台的原因了 ,当一个程序从开始运行,这时虚拟机就开始实例化了,多个程序启动就会存在多个虚拟机实例。程序退出或者关闭,则虚拟机实例消亡,多个虚拟机实例之间数据不能共享。

包装类型

基本类型都有对应的包装类型,让基本类型具备对象的特征,实现更多的功能。基本类型与其对应的包装类型之间的赋值使用自动装箱与拆箱完成。

Integer x = 2;     // 装箱 调用了 Integer.valueOf(2)
int y = x;         // 拆箱 调用了 X.intValue()

Java是一种面向对象编程的语言,但他同时也提供了基本数据类型,提供基本数据类型是出于性能方面的考虑:因为使用对象来处理即使是最简单的计算,系统也销也比较大。

Java中的基本数据类型没有方法和属性,但是在特定场景下,我们必须要利用对象的相关属性,而包装类就是为了让基本数据类型拥有方法和属性,实现对象化交互。这就是我们要学习的自动装箱与拆箱。

基本数据类型 对应包装类
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

装箱 :就是将基本数据类型用他们对应的包装类包装起来。

在装箱的时候自动调用的是Integer的valueOf(int)方法。而在拆箱的时候自动调用的是Integer的intValue方法。

装箱过程是通过调用包装器的 valueOf(xxx) 方法实现的,

拆箱 过程是通过调用包装器的 xxxValue 方法实现的。(xxx代表对应的基本数据类型)。

以Interger类为例,下面看一段代码:

public class Main {
    
    
 
    public static void main(String[] args) {
    
    
        Integer i = 10;
        int n = i;
    }
}

Java自动装箱代码

//boolean原生类型自动装箱成Boolean
    public static Boolean valueOf(boolean b) {
    
    
        return (b ? TRUE : FALSE);
    }
 
 
    //byte原生类型自动装箱成Byte
    public static Byte valueOf(byte b) {
    
    
        final int offset = 128;
        return ByteCache.cache[(int)b + offset];
    }
 
 
    //short原生类型自动装箱成Short
    public static Short valueOf(short s) {
    
    
        final int offset = 128;
        int sAsInt = s;
        if (sAsInt >= -128 && sAsInt <= 127) {
    
     // must cache
            return ShortCache.cache[sAsInt + offset];
        }
        return new Short(s);
    }
 
    //char原生类型自动装箱成Character
    public static Character valueOf(char c) {
    
    
        if (c <= 127) {
    
     // must cache
            return CharacterCache.cache[(int)c];
        }
        return new Character(c);
    }
 
    //int原生类型自动装箱成Integer
    public static Integer valueOf(int i) {
    
    
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
 
    //long原生类型自动装箱成Long
    public static Long valueOf(long l) {
    
    
        final int offset = 128;
        if (l >= -128 && l <= 127) {
    
     // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }
 
    //double原生类型自动装箱成Double
    public static Double valueOf(double d) {
    
    
        return new Double(d);
    }
 
 
    //float原生类型自动装箱成Float
    public static Float valueOf(float f) {
    
    
        return new Float(f);
    }

通过分析源码发现,只有double和float的自动装箱代码没有使用缓存,每次都是new 新的对象,其它的6种基本类型都使用了缓存策略。
    使用缓存策略是因为,缓存的这些对象都是经常使用到的(如字符、-128至127之间的数字),防止每次自动装箱都创建一次对象的实例。
    而double、float是浮点型的,没有特别的热的(经常使用到的)数据的,缓存效果没有其它几种类型使用效率高。

  注意,Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
        Double、Float的valueOf方法的实现是类似的。

二、String

概览

String 被声明为 final,因此它不可被继承。(Integer 等包装类也不能被继承)

在 Java 8 中,String 内部使用 char 数组存储数据。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    
    
    /** The value is used for character storage. */
    private final char value[];
}

在 Java 9 之后,String 类的实现改用 byte 数组存储字符串,同时使用 coder 来标识使用了哪种编码。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    
    
    /** The value is used for character storage. */
    private final byte[] value;

    /** The identifier of the encoding used to encode the bytes in {@code value}. */
    private final byte coder;
}

value 数组被声明为 final,这意味着 value 数组初始化之后就不能再引用其它数组。并且 String 内部没有改变 value 数组的方法,因此可以保证 String 不可变。

不可变的好处

  1. 可以缓存 hash 值

因为 String 的 hash 值经常被使用,例如 String 用做 HashMap 的 key。不可变的特性可以使得 hash 值也不可变,因此只需要进行一次计算。

  1. String Pool 的需要

如果一个 String 对象已经被创建过了,那么就会从 String Pool 中取得引用。只有 String 是不可变的,才可能使用 String Pool。

在这里插入图片描述

  1. 安全性

String 经常作为参数,String 不可变性可以保证参数不可变。例如在作为网络连接参数的情况下如果 String 是可变的,那么在网络连接过程中,String 被改变,改变 String 的那一方以为现在连接的是其它主机,而实际情况却不一定是。

  1. 线程安全

String 不可变性天生具备线程安全,可以在多个线程中安全地使用。

String Pool

字符串常量池(String Pool)保存着所有字符串字面量(literal strings),这些字面量在编译时期就确定。不仅如此,还可以使用 String 的 intern() 方法在运行过程将字符串添加到 String Pool 中。

当一个字符串调用 intern() 方法时,如果 String Pool 中已经存在一个字符串和该字符串值相等(使用 equals() 方法进行确定),那么就会返回 String Pool 中字符串的引用;否则,就会在 String Pool 中添加一个新的字符串,并返回这个新字符串的引用。

String s1 = new String("aaa");
String s2 = new String("aaa");
System.out.println(s1 == s2);           // false
String s3 = s1.intern();
String s4 = s2.intern();
System.out.println(s3 == s4);           // true
String s5 = "bbb";
String s6 = "bbb";
System.out.println(s5 == s6);  // true

new String(“abc”)

使用这种方式一共会创建两个字符串对象(前提是 String Pool 中还没有 “abc” 字符串对象)。

“abc” 属于字符串字面量,因此编译时期会在 String Pool 中创建一个字符串对象,指向这个 “abc” 字符串字面量;
而使用 new 的方式会在堆中创建一个字符串对象。

三、运算

参数传递

Java 的参数是以值传递的形式传入方法中,而不是引用传递。

以下代码中 Dog dog 的 dog 是一个指针,存储的是对象的地址。在将一个参数传入一个方法时,本质上是将对象的地址以值的方式传递到形参中。

public class Dog {
    
    

    String name;

    Dog(String name) {
    
    
        this.name = name;
    }

    String getName() {
    
    
        return this.name;
    }

    void setName(String name) {
    
    
        this.name = name;
    }

    String getObjectAddress() {
    
    
        return super.toString();
    }
}

在方法中改变对象的字段值会改变原对象该字段值,因为引用的是同一个对象。

float 与 double

Java 不能隐式执行向下转型,因为这会使得精度降低。

1.1 字面量属于 double 类型,不能直接将 1.1 直接赋值给 float 变量,因为这是向下转型。

// float f = 1.1;

1.1f 字面量才是 float 类型。

float f = 1.1f;

猜你喜欢

转载自blog.csdn.net/weixin_43821215/article/details/129783345
今日推荐