Java基础语法

138 阅读8分钟

说明:本文章仅用于自己学习,可能有错误的地方,请包涵

基本语法

标识符和关键字的区别

  • 标识符是编写程序的时候为类、方法、变量等,取的名字
  • 关键字是被Java语言赋予了一些特殊含义的标识符。

Java有哪些关键字

分类关键字
访问控制privateprotectedpublic

continue、break和return的区别

这个很简单吧,当然很简单了🥰

  • continue 是跳出当前的这一次循环,继续下一次循环;
  • break 是跳出整个循环体,执行循环下面的语句;
    • 如果是多层循环,则只跳出break语句所在的那一层循环,外层循环继续执行。
  • return 是结束程序执行。

基本数据类型和包装类

Java中有几种基本数据类型

也是很简单的题目哦😀

  • 6种数字类型
    • 4种整数类型:byte、short、int、long;
    • 2种浮点类型:fload、double
  • 1种字符类型:char
  • 1种布尔类型:boolean

这8种基本数据类型的默认值、取值范围及占用空间如下:

基本类型位数字节默认值取值范围
byte810-128-127 (27-2^7, 2712^7 - 1)
short1620-32768(-2^15) ~ 32767(2^15 - 1)
int3240-2147483648 ~ 2147483647
long6480L-9223372036854775808(-2^63) ~ 9223372036854775807(2^63 -1)
char162'u0000'0 ~ 65535(2^16 - 1)
boolen1falsetrue, false

基本类型和包装类型的区别

Java中的8种基本数据类型都有对应的包装类。包装类型其实就是普通的类。两者之间的区别也可以说是基本数据类型与普通类的区别。

他们的区别主要有:

基本类型包装类
存储位置局部变量中的基本类型,存储在Java虚拟机的局部变量表(栈);成员变量中的基本类型,存储在堆中存储在堆中
用途用于定义常量和局部变量包装类型可用于泛型, 集合、方法的传参这个地方保持怀疑,再看下以前的代码
默认值0或NULL
比较方式可以用 == 比较两个值是否相等用equals方法比较两个对象的值

Integer.valueOf源码了解吗

见另一篇文章:Integer.valueOf()源码分析

自动装箱与拆箱

  • 装箱:将基本类型用对应的引用类型包装起来
    • 其实就是调用包装类的valueOf()方法,new一个包装类对象并返回。
    • 如:Integer i = 10 等价于:Integer i = Integer.valueOf(10)(引申,将字符串转为int类型);还有将基本数据类型放入集合中,也会触发基本类型的自动装箱。
  • 拆箱:将包装类型转为基本类型
    • 其实就是调用包装类的xxValue()方法,直接返回一个基本类型。
    • 如:int n = i 等价于:int n = i.intValue();另外基本类型和包装类型比较时,会触发包装类的自动拆箱

当表格中左边列出的基础类型与它们的包装类有如下几种情况时,编译器会自动帮我们进行装箱或拆箱.

  • 进行 = 赋值操作(装箱或拆箱)
  • 进行+,-,*,/混合运算 (拆箱)
  • 进行>,<,==比较运算(拆箱)
  • 调用equals进行比较(装箱)
  • ArrayList,HashMap等集合类 添加基础类型数据时(装箱)

包装类型的缓存机制

Integer.valueOf()源码分析

用缓存机制主要是为了提升性能。使用自动装箱(Integer i = 1)方式创建包装类对象时,会先调用valuaOf()方法进行包装类对象的初始化,比如Integer.valueOf()方法,源码里会先判断传入的整数范围是否在-128到127之间,如果是的话,直接从缓存中获取,否则会new一个新的包装类对象并返回。

  • Byte、Short、Integer、Long四种数字类型,Java缓存了[-128, 127]之间的数据;
    • 其中Integer类型的上界,可以使用 JVM 的启动参数设置最大值。(通过 JVM 的启动参数 -XX:AutoBoxCacheMax=size 修改)
  • Character创建了[0,127]范围内的缓存数据;

如果超出上述范围,则仍然需要到堆中创建新的对象。

两种浮点数类型的包装类 Float,Double 并没有实现缓存机制。

缓存的源码如下:

Integer类

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

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() {}
}

System.identityHashCode(Object x)方法可以返回对象的内存地址,不管该对象的类是否重写了hashCode()方法。

数据比较

基本类型和包装类型的比较

两者之间的比较,会触发包装类型的自动拆箱机制,包装类型转为基本类型之后进行比较。所以只要两者的值相同。比较结果就是true。

包装类型与包装类型的比较

“==”比较。因为包装类型缓存机制的存在,所以:

如果比较的数在指定范围内,数值相等,结果就是true。具体的数值缓存范围是这样的:

  • Byte、Short、Integer、Long四种数字类型,Java缓存了[-128, 127]之间的数据;
  • Character创建了[0,127]范围内的缓存数据;

如果比较的数不在这个范围内,就是两个对象之间的比较,比较的是对象的地址。地址相同则为true,否则为false

“equals”比较。包装类重写了equals方法,比较的是对象的数值,如果数值相同就返回true。

浮点数相关

...


变量

Java有哪些变量类型

  • 成员变量:定义在类中,方法之外的变量,可以被类中的方法、代码块使用。可以被访问修饰符修饰
    • 实例成员变量:new 对象的时候赋值。通过对象.变量名进行访问。
    • 静态成员变量(类变量):定义在类中,方法之外,并且被static关键字修饰。作用域:整个类。在类加载时进行赋值,可以直接通过类.变量名进行访问
  • 局部变量:定义在方法中或代码块中,作用于仅限于当前方法或代码块。局部变量必须在使用前声明,而且不能被访问修饰符修饰
  • 参数变量:方法定义时声明的变量,调用方法时传入的值,作用域仅限于当前方法

成员变量和局部变量的区别

  • 语法:
    • 成员变量是定义在类中、方法之外的变量,可以被访问修饰符修饰;
    • 实例成员变量跟随对象的存在而存在,需要通过实例对象访问;静态成员变量,要加static关键字修饰,可以直接通过类.变量名进行访问;
    • 局部变量是定义在方法或代码块中的变量,不能被访问修饰符修饰。
  • 存储区域:实例成员变量存储在堆内存;静态成员变量在jdk8以后存储在堆中?;局部变量存储在虚拟机栈的局部变量表中
  • 作用域和生命周期:
    • 成员变量可以被类中的任意方法使用;
    • 局部变量的作用域只有当前方法或代码块;
    • 静态成员变量跟类的生存周期一样;实例成员变量跟对象的生存周期一样。
  • 默认值:
    • 成员变量如果没有手动赋值,会自动以类型的默认值进行赋值
    • 局部变量不会自动赋值,在使用前必须赋值
public class Variables {
    public static Integer j;
    public static void main(String[] args) {
        Integer i;
        // 成员变量没有赋值就使用,编译会报错
        System.out.println(i);
        // 没有手动赋值,会给一个默认值null
        System.out.println(j);
    }
}

字符型常量和字符串常量的区别

  • 定义:字符型常量是单引号括起来的一个字符;字符串常量是双引号括起来的0个或多个字符
  • 含义:字符型常量就是ASCII值,可以直接参与+-运算:字符串常量是一个地址值
  • 占用内存大小:在Java中,1个字符占2字节;字符串占多个字节;

关键字

static关键字

final关键字

参考文章:JavaGuide(Java面试 + 学习指南)