JAVA面试知识点总结--数据类型

版权声明:本文为博主原创文章,转载请在明显的位置注明出处。如果觉得文章对你有用,给我点个赞呗~ https://blog.csdn.net/sayWhat_sayHello/article/details/81879593

一、数据类型

基本数据类型

数值类型:

数据类型 封装类型 存储需求(字节) 取值范围=(-2^(8*存储需求)~2^(8*存储需求)-1)
byte Byte 1 -2^8~2^7-1(-128~127)
short Short 2
int Integer 4
long Long 8
float Float 4
double Double 8

面试考点:取值范围,运算,拆装箱,比较,类型转换

运算and类型转换

image
实心箭头代表无信息丢失,虚箭头表示有精度损失

案例:

byte i = 1;
i = i + 1;//报错,因为运算的时候byte转换成了int类型
i = (byte)(i + 1);//可以,使用了强制类型转换
i += 1;//可以,这种结合赋值会隐式进行强制类型转换

注意:结合赋值会隐式进行强制类型转换

位运算里:~n = -n - 1

自动装拆箱and比较

自动装箱和拆箱大部分人的印象应该就是这样子的:

Integer i = 1;//自动将int类型装箱为Integer
int a = new Integer(5);//自动拆箱为int

那么面试的考点应该是下面这样子的:

  1. 基本型和基本型封装型进行==运算符的比较,基本型封装型将会自动拆箱变为基本型后再进行比较。
  2. 两个Integer类型进行“==”比较,还要看Integer对象创建的方式,这里还有一个缓存池的概念。Integer缓存的是-128~127
  3. 两个基本型的封装型进行equals()比较,首先equals()会比较类型,如果类型相同,则继续比较值,如果值也相同,返回true
  4. 基本型封装类型调用equals(),但是参数是基本类型,这时候,先会进行自动装箱,基本型转换为其封装类型,再进行3中的比较。
Integer i = 9;
int j = 9;
System.out.println(i == j);//true,i自动拆箱,然后进行比较

Integer k = 9;
Integer kk = new Integer(9);
Integer kkk = Integer.valueOf(9);
System.out.println(i == k);//true。i,k创建方式不是new,而且值在缓存池里,所以==比较对象的会是同一个地址
System.out.println(i == kk);//false。kk是new的,所以内存地址不一样。
System.out.println(i == kkk);//true。如果值在缓存池里valueOf会直接返回对应缓存,否则调用new Integer

Integer ii = 128;
Integer jj = 128;
System.out.println(ii == jj);//false.如果值在缓存池里valueOf会直接返回对应缓存,否则调用new Integer

System.out.println(i.equals(k));//方法为public boolean equals(Object obj)
System.out.println(i.equals(kk));//

基本类型对应的缓冲池如下:

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

boolean类型:

封装类型:Boolean,取值为true|false.

面试考点:逻辑符的短路

逻辑符的短路:

逻辑符的短路表示按顺序执行&&,||时,如果前面语句满足了判断那么就不会执行后面的语句:

if(true||5/0==0){
    ...
}

执行前半句得到true,逻辑短路不会执行后面的语句,故不会报错。

实际上位运算符&,|也可以表示与和或,代表的是一种非短路的运算。如果上述条件改为|那么就会报错。

char类型:

char原本用于表示单个字符。现在可以描述一些Unicode字符。封装类型为:Character,取值范围现在是0~2^16-1.

面试考点:封装类型,常见char对应int值

字符 ASCII码值
‘0’ 48
‘a’ 97
‘A’ 65

注意:当赋值为整型的时候不是代表对应的值,而是ASCII值:

char a = 1;
char b = '1';//a!=b

image

String类型

string的面试考点一般有 判断是否相等,equals(),不可变性,StringBuffer/StringBuilder的区别

内部实现

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

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

常用的String的创建

  1. String s = "java";我们把这类创建称为字面量 方式,直接使用双引号将字符数组value[]括起来。
  2. String s = new String("java");使用构造函数构造String对象。

之所以要区分这两种不同创建方式是因为他们在创建String对象的时候会有不同的表现形式。

字面量创建:

使用字面量的方式创建,首先JVM会到字符串常量池中检查是否有内容为java的对象存在。

如果不存在,那么会先在在堆内存创建一个内容为java的String对象,然后将指向该对象的内存地址引用存入字符串常量池中

如果存在则返回该引用。

如果是String s = "ja"+"va";这样的方式创建字符串,由于编译优化,那么在编译器会直接在字符串常量池创建内容为java的引用,而没有ja,va这两个。

但是如果是String s1 = "ja";String s = s1 + "va";由于无法在编译器确定s的内容,jvm会在运行时确认。而在运行时确认需遵循以下规则:只要s1是变量,不论s1指向池中的字符串对象还是堆中的字符串对象,运行期s1 + “aa”操作实际上是编译器创建了StringBuilder对象进行了append操作后通过toString()返回了一个字符串对象存在heap上。

在JDK6.0及之前版本,字符串常量池是放在Perm Gen区(也就是方法区)中;
在JDK7.0版本,字符串常量池被移到了堆中了。因为方法区的内存太小,只能存放1009个,而现在可以通过指定-XX:StringTableSize参数初始化字符串常量池的大小。

构造方法创建:

使用构造方法创建时,不过字符串常量池是否有相应的内容的String对象引用,都会在堆上新建一个String对象。

对于上面使用new创建的字符串对象,如果想将这个对象的引用加入到字符串常量池,可以使用intern方法。

调用intern后,首先检查字符串常量池中是否有该对象的引用,如果存在,则将这个引用返回给变量,否则将引用加入并返回给变量。

案例:

String a = "java";
String b = "java";
String c = new String("java");
String cc = String.valueOf("java");
String ccc = new StringBuilder("java").toString();
String d = "ja"+"va";
System.out.println(a == b);//true
System.out.println(a == d);//true
System.out.println(a == c);//false
System.out.println(a == cc);//true
System.out.println(a == ccc);//false

StringBuffer和StringBuiler:

  1. StringBuffer线程安全,StringBuiler线程非安全。
  2. StringBuiler牺牲了对方法的互斥锁,所以运行速率比StringBuffer高。
  3. 都继承了AbstractStringBuilder。

猜你喜欢

转载自blog.csdn.net/sayWhat_sayHello/article/details/81879593