java se基础(四)基本数据类型与运算

1. Java的基本数据类型/引用类型有哪些?知道自动装箱和拆箱吗?

4类8种基本数据类型。4整数型,2浮点型,1布尔型,1字符型

类型/th> 存储取值范围默认值包装类
byte8最大存储数据量是255,最小-2(7),最大2(7)-1,即:[-128~127](byte) 0Byte
short16最大数据存储量是65536,[-2(15),2(15)-1],±3万 [-32768,32767](short) 0Short
int32最大数据存储容量是2(31)-1,范围:[-2(31),2(31)-1],±21亿[ -2147483648, 2147483647]0Integer
long64最大数据存储容量是2(64)-1,范围:[-2(63),2(63)-1], ±922亿亿(±(922+16个零))(byte) 0LLong
float32数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F0.0fFloat
double64数据范围在4.9e-324~1.8e308,赋值时可以加d或D也可以不加0.0dDouble
boolean1false,truefalseBoolean
char16存储Unicode码,用单引号赋值‘\u0000’ (null)Character
  • 引用数据类型

类(class)、接口(interface)、数组

  • 自动装箱和拆箱

基本数据类型和它对应的封装类型之间可以相互转换。自动拆装箱是jdk5.0提供的新特特性,它可以自动实现类型的转换
装箱:从基本数据类型到封装类型叫做装箱
拆箱:从封装类型到基本数据类型叫拆箱

jdk 1.5
public class TestDemo {
    public static void main(String[] args) {
        Integer m =10;
        int i=m;
    }
}

​ 上面的代码在jdk1.4以后的版本都不会报错,它实现了自动拆装箱的功能,如果是jdk1.4,就得这样写了

jdk 1.4
public class TestDemo {
    public static void main(String[] args) {
        Integer b = new Integer(210);
        int c = b.intValue();
    }
}

2. ValueOf缓存池

new Integer(123)与Integer.valueOf(123)的区别在于,new Integer(123) 每次都会新建一个对象,而 Integer.valueOf(123) 可能会使用缓存对象,因此多次使用 Integer.valueOf(123) 会取得同一个对象的引用。

Integer x = new Integer(123);
Integer y = new Integer(123);
System.out.println(x == y);    // false
Integer z = Integer.valueOf(123);
Integer k = Integer.valueOf(123);
System.out.println(z == k);   // true

编译器会在自动装箱过程调用 valueOf() 方法,因此多个 Integer 实例使用自动装箱来创建并且值相同,那么就会引用相同的对象。

Integer m = 123;
Integer n = 123;
System.out.println(m == n); // true

valueOf() 方法的实现比较简单,就是先判断值是否在缓存池中,如果在的话就直接使用缓存池的内容。

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

在 Java 8 中,Integer 缓存池的大小默认为 -128~127。

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;
}

Java 还将一些其它基本类型的值放在缓冲池中,包含以下这些:

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
因此在使用这些基本类型对应的包装类型时,就可以直接使用缓冲池中的对象。

3.i++和++i有什么区别

i++是在程序执行完毕后进行自增,而++i是在程序开始执行前进行自增。

i++的操作分三步

  1. 栈中取出i
  2. i自增1
  3. 将i存到栈

所以i++不是原子操作,上面的三个步骤中任何一个步骤同时操作,都可能导致i的值不正确自增

++i

在多核的机器上,cpu在读取内存i时也会可能发生同时读取到同一值,这就导致两次自增,实际只增加了一次。

i++和++i都不是原子操作

原子性:指的是一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程打断。

4. 位运算符

Java定义了位运算符,应用于整数类型(int),长整型(long),短整型(short),字符型(char),和字节型(byte)等类型。

下表列出了位运算符的基本运算,假设整数变量A的值为60和变量B的值为13

A:0011 1100

B:0000 1101
这里写图片描述

5. 原码、补码、反码是什么

机器数
一个数在计算机中的二进制表示形式,叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号,正数为0,负数为1。

比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011 。那么,这里的 00000011 和 10000011 就是机器数。

真值
因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。

例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1

原码
原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:

[+1]原 = 0000 0001

[-1]原 = 1000 0001

第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:

[1111 1111 , 0111 1111],即:

[-127 , 127]

原码是人脑最容易理解和计算的表示方式.

反码
反码的表示方法是:

正数的反码是其本身;
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。
[+1] = [00000001]原 = [00000001]反

[-1] = [10000001]原 = [11111110]反

可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算。

补码
补码的表示方法是:

正数的补码就是其本身;
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
[+1] = [00000001]原 = [00000001]反 = [00000001]补

[-1] = [10000001]原 = [11111110]反 = [11111111]补

对于负数, 补码表示方式也是人脑无法直观看出其数值的。 通常也需要转换成原码在计算其数值。

6. 不用额外变量交换两个整数的值

如果给定整数a和b,用以下三行代码即可交换a和b的值

a = a ^ b;
b = a ^ b;
a = a ^ b;

假设a异或b的结果记为c,c就是a整数位信息和b整数位信息的所有不同信息。比如:a=4=100,b=3=011,ab=c=111
a异或c的结果就是b,比如:a=4=100,c=111,a^c=011=3=b
b异或c的结果就是a,比如:b=3=011,c=111,b^c=100=4=a
说明:位运算的题目基本上都带有靠经验积累才会做的特征,也就是准备阶段需要做足够多的题,面试时才会有良好的感觉。

7. 不使用运算符进行a+b操作

a^b; 得到不含进位之和
(a&b)<<1; 进位
只要进位不为零,则迭代;否则返回

public class Solution {
    /*
     * @param : An integer
     * @param : An integer
     * @return: The sum of a and b
     */
    public int aplusb(int a, int b) {

        int sum_without_carry, carry;
        sum_without_carry = a^b; //没有进位的和
        carry = (a&b)<<1; //进位
        if(carry==0)
            return sum_without_carry;
        else 
            return aplusb(sum_without_carry, carry);   
    }
};

8. &和&& 、|和||的区别?【阿里实习生面试】

(1)&&和&都是表示与,区别是&&只要第一个条件不满足,后面条件就不再判断。而&要对所有的条件都进行判断。

// 例如:
public static void main(String[] args) {  
    if((23!=23)&&(100/0==0)){  
        System.out.println("运算没有问题。");  
    }else{  
        System.out.println("没有报错");  
    }  
}  
// 输出的是“没有报错”。而将&&改为&就会如下错误:
// Exception in thread "main" java.lang.ArithmeticException: / by zero

原因:

&&时判断第一个条件为false,后面的100/0==0这个条件就没有进行判断。

&时要对所有的条件进行判断,所以会对后面的条件进行判断,所以会报错。

(2)||和|都是表示“或”,区别是||只要满足第一个条件,后面的条件就不再判断,而|要对所有的条件进行判断。 看下面的程序:

public static void main(String[] args) {  
    if((23==23)||(100/0==0)){  
        System.out.println("运算没有问题。");  
    }else{  
        System.out.println("没有报错");  
    }  
}
// 此时输出“运算没有问题”。若将||改为|则会报错。

原因
||判断第一个条件为true,后面的条件就没有进行判断就执行了括号中的代码
而|要对所有的条件进行判断, 所以会报错

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值