面试:Java 关键字

1. 变量命名有哪些规则

标识符只能是字母、数字、下划线 _$ 组成,并且第一个字符必须是字母、下划线 或 $,也就是说第一个字符不能是数字。

2. break, continue, return 的区别

其他不讲了。

定义标识来跳出多重循环:


public class Break{

public static void main(String[] args){

// 定义标识

out:

for(int i = 0; i < 5; i++){

for(int j = 0; j < 5; j++){

if(j >= 2)

// break 到标识(双重循环)

break out;

System.out.println(j);

}

}

System.out.println("break");

}

}



// 运行结果为

// 0

// 1

// break

定义标签:标识符 + 冒号,方便使用 break 和 continue

3. final, finally, finalize 有什么区别

3.1 final

final 用于声明属性、方法和类,分别标识不可变、方法不可覆盖和类不可被继承

final 属性: 被 final 修饰的变量是 引用不可变

final 方法:此方法不可被子类覆盖(但子类任能使用该方法);另外还有一种称为inline机制,当调用一个被声明为final的方法适,直接将方法主体插入到调用处,而不是进行方法调用(类似于 C++ 中的 inline)。

final 类:此类不能继承,所有的方法不能被重写。但不表示 final 类的成员变量不可变。还有一个类不能既被声明为 abstract,又被声明为 final。

3.2 finally

try-catch-finally

不管是否出现异常, finally 中的代码一定会执行,一般用来释放资源。

3.3 finalize

finalizeObject 类的一个方法,在垃圾回收器执行时会调用被回收的对象的 finalize() 方法

JDK 中哪些类不能被继承:final 修饰的类、一般比较基本的类型或防止扩展类无意间破坏原来方法实现的类型都应该是 final 的,在 JDK 中,String, StringBuffer 等都是基本类型,所以都是不能被继承的。

4. assert 有什么用

assert 是一种软件调试的方法,提供了一种在代码中进行正确检查的机制。主要作用是对一个boolean表达式进行检查,如果表达式值为 false,说明程序处于不正确状态,系统需要提供警告信息并退出程序。

在实际开发中,assert主要用来保证程序的正确性,通常在程序开发和测试时使用。软件发布之后,assert 检查默认是被关闭的。

assert 有两种表达式:assert expression1assert expression1: expression2(expression1 是一个 boolean 表达式,expression2 表示一个基本类型或者对象)


public clss Test{

public static void main(String[] args){

assert 1 + 1 == 2;

System.out.println("assert1 ok");

assert 1 + 1 == 3 : "assert failed, exit";

System.out.println("assert2 ok");

}

}

对于上面代码,当执行 javac Test.java; java Test时,输出的结果为:


assert1 ok

assert2 ok

因为默认 assert 是被忽略的

但开启 -ea 模式,assert 就生效了

assert的应用范围主要包括:

  1. 检查控制流

  2. 检查输入参数是否有效

  3. 检查函数结果是否有效

  4. 检查程序不变量

assert 一般在调试时使用,如果不小心用 assert 控制了程序的流程业务,在调试结束后去掉 assert 意味着修改了正常逻辑,这样是很危险的。而 if 判断是逻辑判断,本身就可以控制程序流程。

java 的 assert 是运行时开启。

5. static 关键字有那些用

  1. 第一:为特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关。

  2. 实现某个方法或属性与类,而不是对象关联,在不创建对象的情况下就可以调用方法或使用类的属性。

具体而言,static 只有 4 种情况:成员变量、成员方法、代码块、内部类。

static 代码块

static 代码块是独立于成员变量和成员函数的代码块的,它不在任何一个方法体内,JVM 在 加载类 时会执行 static 代码块,如果又多个 static 代码块, JVM 会按顺序来执行。

static 经常被用来初始化静态变量。

不能在成员函数内部定义 static 变量。

6. 使用 switch 时有哪些注意事项

switch(expr) 时,expr 只能是一个枚举常量(内部也是由整型或字符型实现)或一个整数表达式,其中整数表达式可以是基本类型 intInteger,当然也包括不同长度的整型,例如 short。由于 byteshortchar 类型值都能隐式转换为 int 型,因此可以作为 switch 表达式、而 longfloatdoubleString 等类型不能隐式转换为 int,所以不能作为 switch 表达式,除非强制转换。

case 语句之后可以是直接的常量数值比如1、2,也可以是一个常量表达式比如 1+2 等,还可以是 final 常量,例如final int a = 0,但补鞥呢是变量或待遇变量的表达式。

Java 7 开始支持 String 类型,以下是 String 类型示例:

从本质讲,其实 switch 对字符串的支持,也是和 int 类型值的匹配(hashCode()

7. volatile 有什么用

Java 有时候为了提高运行效率,编译器会把经常访问的变量缓存起来,程序读取遍量的时候可能会从缓存读,但缓存值可能存在与内存值不一致的情况。

volatile 是一个类型修饰符,修饰 被不同线程访问和修改的变量。被 volatile 定义的变量,每次都是从对应的内存中提取,而不会利用缓存。这样所有线程在任何时候看到的变量值都是相同的。

这是停止线程最常用的方法。但是 volatile 不能保证操作原子性。

对于volatile修饰的变量,jvm虚拟机只是保证从主内存加载到线程工作内存的值是最新的

例如假如线程1,线程2 在进行read,load 操作中,发现主内存中count的值都是5,那么都会加载这个最新的值

在线程1堆count进行修改之后,会write到主内存中,主内存中的count变量就会变为6

线程2由于已经进行read,load操作,在进行运算之后,也会更新主内存count的变量值为6

导致两个线程及时用volatile关键字修改之后,还是会存在并发的情况。

因此,一般情况下 volatile 不能代替 sychronized,此外 volatile 会阻止编译器对代码进行优化,降低执行效率。除非迫不得已,能不用 volatile 就不用。

8. instanceof 有什么用

instanceof 是个二元运算符,判断一个引用类型的变量所指向的对象是否是一个类(或接口、抽象类、父类)的实例。

返回 boolean

s instanceof String

9. strictfp 有什么用

strict float point 精确浮点,用来确保浮点数运算的准确性。

如果没有指定 strictfp,计算结果可能不进去。

当一个类被 strictfp 修饰时,所有方法会自动被 strictfp 修饰。因此 strictfp 保证了浮点数运算的精确性。


public strictfp class Test{

public static void testStrictfp(){

float f = 0.12265f;

double d = 0.03496421d;

double sum = f + d;

System.out.println(sum);

}



public static void main(String[] args){

testStrictfp();

}

}

// 0.15861420949932098