问题及答案来源自《Java程序员面试笔试宝典》第四章 Java基础知识 4.3关键字
1、变量命名有哪些规则
Java标识符:变量名、函数名、数组名统称为标识符
Java语言规定标识符只能由字母(a~z、A~Z)、数字(0~9)、下划线(_)和$组成
并且标识的第一个字符必须是字母、下划线或$,另外标识中不能包含空白字符(换行符、空格和制表符)
另外要注意在Java中变量名是区分大小写的,例如Count和count就是两个不同的标识符
2、break、continue以及return有什么区别
break、continue、return的区别如下:
- break用于直接强行跳出当前循环,不再执行剩余代码
- continue用于停止当此循环,回到循环起始处,进入下一次循环操作
- return表示从一个方法返回(返回值或其他复杂类型),使程序控制返回到调用该方法的地方
另外break也可以跳出多层循环:
1 public class Break{ 2 public static void main(String[] args) { 3 out: 4 for(int i=0;i<5;i++){ 5 for(int j=0;j<5;j++){ 6 if(j>=2){ 7 break out; 8 } 9 System.out.println(j);10 }11 }12 System.out.println("break");13 }14 }
程序运行结果为:
0
1
break
3、final、finally和finalize有什么区别
final、finally、finalize三者的区别如下:
- final用于声明属性、方法和类,分别表示属性不可变、方法不可覆盖和类不可被继承(不能再派生出新的子类)
- finally作为异常处理的一部分,只能用在try/catch语句中,附带一个语句表示这个语句最终一定被执行
- finalize是Object类的一个方法,在垃圾回收器执行时会调用被回收对象的finalize方法
关于final:
1 final修饰类:不能被继承(没有子类),但是可以是其他类的子类 2 3 final修饰成员变量: 4 被final修饰的成员变量必须在创建对象之前有确定的值 5 被final修饰的成员变量只能赋值一次(要么声明的时候直接赋值,要么在构造函数中赋值) 6 7 final修饰成员方法: 8 不能被子类重写 9 10 final修饰局部变量:11 基本类型局部变量 - 只能赋值一次(实际上就是常量)12 引用类型局部变量 - 只能赋值一次但其中对象里的内容是可以改变的(地址指向空间中的内存内容可以改变)13 14 被final修饰的变量不可变 - final指的是引用不可变,即它只能指向初始化时指向的那个对象,而不关心15 16 另外一个类不能即被声明为abstract,又被声明为final
关于finally:
finally最终一定被执行,经常被用在需要释放资源的情况下,示例代码如下:
1 Connection conn = null; 2 Statement stmt = null; 3 try{ 4 conn = DriverManager.getConnection(url, userName, password); 5 stmt = conn.createStatement(); 6 tmt.executeUpdate(update); // 执行一条update语句 7 stmt.close(); 8 conn.close(); 9 } catch(Exception e){10 e.printStackTrace();11 } finally{12 if(stmt!=null){13 stmt.close();14 }15 if(conn!=null){16 conn.close();17 }18 }
在上述代码中不管程序运行是否出现异常,finally的代码一定会运行,这样能保证在任何情况下数据库的连接资源都能被释放
关于finalize:
一旦垃圾回收器准备好释放对象占用的空间,将首先调用finalize方法,并且在下一次垃圾回收动作发生时
才会真正回收对象占用的内存
常见笔试题 - Java中哪些类是不能继承的?
不能继承的类是用final关键字修饰的类,一般比较基本的类型为防止拓展类无意间破坏原来方法的实现,就用final修饰类,
在Java中String、StringBuffer等都是基本类型,所以String、StringBuffer等类都是不能继承的
4、assert有什么作用
assert是什么:
assert就是断言,是一种软件调试的方法,提供了在代码中进行正确性检查的机制
assert的作用:
对一个boolean表达式进行检查,一个正确运行的程序必须保证这个boolean表达式的值为true,若为false
则说明程序不正确,需要提供警告信息并退出程序
assert的使用:
1 // 使用assert2 public class code9_useAssert {3 public static void main(String[] args) {4 assert 1 + 1 == 2;5 System.out.println("assert1 OK");6 assert 1 + 1 == 3 : "assert failed, exit";7 System.out.println("assert2 OK");8 }9 }
Java中的assert和C语言中的assert的不同:
- Java中使用assert关键字实现功能,而C语言中使用的是库函数
- C语言中的assert是在编译时开启,而Java中是在运行时开启
5、static关键字有哪些作用
static关键字的主要作用有两个:
- 为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关
- 实现某个方法或属性与类而不是与对象关联在一起
static的作用(详细):
- static是Java关键字,是一个修饰符,用于修饰成员(成员变量,成员函数)
- static修饰的成员变量称之为静态变量或类变量,修饰的成员函数称之为静态函数或类函数
- static修饰的成员被所有的对象共享,static成员优先于对象存在,因为static的成员随着类的加载就已经存在
- static修饰的成员多一种调用方式,可以直接用类名调用(类名.静态成员),当然也可以用对象名来调用
- static修饰的数据是共享数据,对象中的存储的是特有的数据
static主要有4种使用情况:成员变量、成员方法、代码块和内部类,详细如下:
static成员变量:
static成员变量就是静态变量,静态变量属于类,在内存中只有一个复制(所有实例都指向同一个地址),
只要静态变量所在的类被加载,这个静态变量就会被分配空间,就可以使用了(类.静态变量或对象.静态变量)
static成员方法:
static方法(静态方法)中不能使用this和super关键字,不能调用非static方法,不能访问非static变量,只能
访问所属类的静态成员变量和静态成员方法
static代码块:
static代码块即静态代码块在类中是独立于成员变量和成员函数的代码块的,它不在任何一个方法体内,
JVM在加载类时会执行静态代码块,静态代码块常用来初始化静态变量,注意static代码块只会执行一次
static代码块代码如下:
1 public class Test{ 2 private static int a; 3 static{ 4 Test.a = 4; 5 System.out.println(a); 6 System.out.println("static block"); 7 } 8 public static void main(String[] args){ 9 }10 }
程序运行结果:
4
static block
static内部类:
static内部类是指被声明为static的内部类,它可以不依赖于外部类实例对象而被实例化,而通常的内部类需要在
外部类实例化后才能实例化
静态内部类不能与外部类有相同的名字,不能访问外部类的普通成员变量,只能访问外部类中的静态成员和静态方法
引申1 - 什么是实例变量?什么是局部变量?什么是类变量?什么是final变量?
实例变量:变量归对象所有,每实例化一个对象就会创建一个副本并初始化,如果没有显式初始化那么会初始化默认值
局部变量:在方法中定义的变量,在使用前必须初始化
类变量:用static修饰的属性,变量归类所有,只要类被加载这个变量就可以使用
final变量:表示变量为常量,不能被修改(引用不能被修改)
引申2 - static与final结合使用表示什么意思?
在Java中static和final结合用来修饰成员变量和成员方法,类似C/C++中的全局常量
- 对于变量来说:若使用static final来修饰,表示一旦赋值就不可修改,并且可以通过类名访问
- 对于方法来说:若使用static final来修饰,表示该方法不可覆盖,并且可以通过类名直接访问
引申3 - 被static修饰的成员的特点如下:
- 存在方法区中的静态区,只有一个空洞
- 静态是优于对象存在
- 访问静态成员可以通过类名也可以通过对象名(建议通用类名访问)
6、使用switch有哪些注意事项
switch的注意事项:
- switch()内必须为字符型或整型(Java7支持String类型)
- case后可以是常量或常量表达式,但不能有变量
- 如果没有break,switch程序会一直执行下去直到遇到break或switch结束
switch对字符串的支持原理:
switch对字符串的支持其实就是int类型值的匹配,它的实现原理是通过case后面的String对象调用hashCode()方法,
得到一个int类型的hash值,然后用这个hash值来唯一标识这个case。当匹配时,首先调用字符串hashCode方法,
获取hash值,用这个hash值来匹配所有case,如果没有匹配成功,说明不存在,如果匹配成功,接着调用
字符串的String.equals()方法进行匹配
由原理可以看出String变量不能为null,同时case子句中使用的字符串也不能为null
7、volatile有什么作用
背景描述:
在用Java编写的程序中,有时候为了提高程序的运行效率,编译器会自动对其进行优化,把经常访问的变量缓存起来,
程序在读取这个变量时有可能会直接从缓存(寄存器)中读取值,而不会去内存中读取值
这样做的好处是提高了程序的运行效率,但当多线程编程时,变量的值可能因为别的线程改变了,而该缓存的值
却不会相应改变,从而造成应用程序读取的值和实际的变量值不一致
volatile的作用:
volatile是一个类型修饰符,它是被设计用来修饰被不同线程访问和修改的变量。被volatile类型定义的变量,系统
每次用到它都是直接从对应的内存中读取数据,而不会利用缓存,于是就避免了上述情况的发生。在使用了volatile
修饰成员变量后,所有线程在任何时候所看到变量的值都是一样的
volatile的缺点:
- 不能保证操作的原子性(不能替代sychronized)
- 使用volatile会组织编译器对代码的优化(降低程序运行效率)
8、instanceof有什么作用
instanceof是Java中的一个二元运算符
其主要作用是判断一个引用类型的变量所指向的对象是否是一个类(或接口、抽象类、父类)的实例
即判断它左边的对象是否是它右边的类的实例,该运算符返回boolean类型的数据
instanceof使用代码如下:
1 public class test {2 public static void main(String[] args) {3 String s = "hello";4 int[] a = {1, 2};5 System.out.println(s instanceof String); // true6 System.out.println(s instanceof Object); // true7 System.out.println(a instanceof int[]); // true8 }9 }
9、strictfp有什么作用
stricfp =》strict float point
stricfp指精确浮点,它用来确保浮点数运算的准确性