【面试题】Java基础

若你困于无风之地,我将为你奏响高空之歌


1. 字符型常量和字符串常量

字符型常量相当于一个整数值,即ASSIC值,可以参与表达式运算。而字符串常量代表一个地址,即该字符串在内存中存放的位置。在占用内存空间上,字符型常量只占两个字节,而字符串常量占若干个字节。并且char是Java中的基本数据类型,而String不是。


2. 字符串常量池

JVM 为了提升性能和减少内存开销,避免同一内容字符串的重复创建,维护了一块特殊的内存空间,即全局字符串常量池。当需要使用某一字符串时,先去字符串常量池中查看该字符串是否存在,若存在,则直接使用。若不存在,则初始化,将该字符串放入字符串常量池中。

JDK1.6及以前,常量池在方法区,这时的方法区也叫做永久代;
JDK1.7的时候,方法区合并到了堆内存中,这时的常量池也可以说是在堆内存中;
JDK1.8及以后,方法区又从堆内存中剥离出来了,但实现方式与之前的永久代不同,这时的方法区被叫做元空间,常量池就存储在元空间。


3. String str="aaa"与 String str=new String(“aaa”) 的区别

String a = “aaa” :程序运行时会在常量池中查找”aaa”字符串,若没找到,会将”aaa”字符串放进常量池,再将其地址赋给a;若找到,将找到的”aaa”字符串的地址赋给a。
String b = new String("aaa"):程序会在堆内存中开辟一片新空间存放新对象,同时会将”aaa”字符串放入常量池,相当于创建了两个对象,无论常量池中有没有”aaa”字符串,程序都会在堆内存中开辟一片新空间存放新对象。

验证代码:

public class testString {
    public static void main(String[] args) {
        String str1 = "aaa";
        String str2 = "aaa";
        System.out.println("str1 == str2 " + (str1 == str2));

        String str3 = new String("aaa");
        String str4 = new String("aaa");
        System.out.println("str3 == str4 " + (str3 == str4));
    }
}

执行结果:

在这里插入图片描述


4. Java 中的基本数据类型

Java 中基本数据类型只有 8 个 :byteshortintlongfloatdoublecharboolean,其他的如 String 等都是引用类型(reference type)


5. String 的不可变性

1. 不可变性定义

不可变:
类的实例一旦创建后,其内容(状态)就不可改变。即一个对象一旦被创建后,整个对象就是不可变的。包括属任何性和状态。

理解 String 的不可变性,我们先要明确,字符串对象的概念。请看如下代码:

        String string = "LiuWanQing";
        string = "come on!";

等号左侧的 string 是存放在栈上的临时变量,而等号右面的 "LiuWanQing" "come on!" 才是字符串对象,其存放在堆上。字符串对象是不可变的!!!

2. String 不可变的原因

我们可以观察一下,String 的实现源码

final修饰变量:

  1. 基础数据类型:一旦初始化,便不能改变其值。
  2. 引用类型(如 String):一旦初始化,便不能改变其引用,也就是不能指向一个新的对象,但是仍然可以修改引用指向的对象内容。

通过观察源码,我们可以得到不可变的原因为:

value使用final修饰;没有暴露成员变量;内部方法不会改动 value;类使用final修饰,不可继承

在这里插入图片描述

3. 不可变的好处

可用来做 HashMap 的 key: HashMap 内部实现是通过 key 的 hashcode 来确定 value 的存储位置,因为字符串是不可变的,所以当创建字符串时,它的 hashcode 被缓存下来,不需要再次计算,所以相比于其他对象更快。


6. 包装类型

Java 为每一个基本数据类型都引入了对应的包装类型(wrapper class),两者之间可以互相转换。

装箱: 把基本类型转换成包装类型的过程叫做装箱(boxing)

自动装箱:

jdk1.5 开始引入了自动装箱 / 拆箱机制,自动将基本数据类型转化为对应的封装类型,成为一个对象以后就可以调用对象所声明的所有的方法

        public static void main(String[] args) {  
            // 声明一个Integer对象,用到了自动的装箱:解析为:Integer num = Integer.valueOf(9);
         	Integer num = 9;
        } 

拆箱: 把包装类型转换成基本类型的过程叫做拆箱(unboxing)

自动拆箱:

        public static void main(String[] args) {  
            // 声明一个Integer对象
         	Integer num = 9;
            // 进行计算时隐含的有自动拆箱
      		System.out.print(num--);
        }  

原始类型:

boolean,char,byte,short,int,long,float,double

包装类型:

Boolean,Character,Byte,Short,Integer,Long,Float,Double


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值