面试遇到的基础题
- 下面代码的输出结果
public class Parent {
static { System.out.println("Parent - 静态代码块"); }
{ System.out.println("Parent - 代码块"); }
public Parent() {
System.out.println("Parent - 构造");
}
}
public class Child extends Parent{
static { System.out.println("Child - 静态代码块");}
{ System.out.println("Child - 代码块"); }
public Child() {
System.out.println("Child - 构造");
}
}
public static void main(String[] args) {
new Child();
}
解析:子类继承父类,实例化子类时,会先实例化父类,但是静态代码块会在编译时执行
Parent - 静态代码块
Child - 静态代码块
Parent - 代码块
Parent - 构造
Child - 代码块
Child - 构造
- main 方法为什么是静态的?能不能改为非静态?
main()方法一定是静态的,不能改为非静态;虽然去掉static依然可以编译成功,但是运行时会出错。没有改为非静态,则JVM调用时就必须实例化该类,就需要调用构造函数,如果该类只有有参构造函数,就会出现歧义。
- 在 Java 中,为什么不允许从静态方法中访问非静态变量?
Java 中不能从静态上下文访问非静态数据只是因为非静态变量是跟具体的对象实例关联的,而静态的方法却没有和任何实例关联
- Java 中是否可以覆盖(override)一个static 的方法?
Java 中 static 方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而 static 方法是编译时静态绑定的。static 方法跟类的任何实例都不相关,所以概念上不适用。
- 静态域和静态代码
public class SingletonTest2 {
static {
singleton = new SingletonTest2();
}
private static SingletonTest2 singleton = null ;
private SingletonTest2(){ }
public static void main(String[] args) {
System.out.println(singleton); // null
}
}
没有任何打印,因为没有获取到SingletonTest2
public class SingletonTest2 {
private static SingletonTest2 singleton = null;
static {
singleton = new SingletonTest2();
}
private SingletonTest2() {
}
public static void main(String[] args) {
System.out.println(singleton);
//com.learn.concurrency.example.singleton.SingletonTest2@7adf9f5f
}
}
可以正确打印
总结:静态变量一定要定义在静态代码的前面
- 下面main函数的输出结果
public static void main(String[] args) {
Integer i1 = new Integer(23);
Integer i2 = new Integer(23);
System.out.println(i1 == i2);
Integer i3 = 23;
Integer i4 = 23;
System.out.println( i3 == i4);
Integer i5 = 500;
Integer i6 = 500;
System.out.println(i5 == i6);
}
false true false
分析:i1和i2 是new 的,自然不相等;i3 和i4,在缓存 -128 and 127 中;i5和i6不在,需要new
- 下面程序的输出结果
public static void main(String[] args) {
System.out.println(1.0/0);
System.out.println(-1.0/0);
System.out.println(0.0/0);
}
Infinity // 正无穷
-Infinity // 负无穷
NaN // 空
- 下面程序的输出结果
public class Child extends Parent{
public Child() {
sayHello();
}
public void sayHello(){
System.out.println("Child Hello ");
}
public static void main(String[] args) {
new Child();
}
}
class Parent{
public Parent() {
sayHello();
}
public void sayHello(){
System.out.println("Parent Hello ");
}
}
// new Child()会先实例化父类, 由于方法被覆盖,父类调用的sayHello是已经被覆盖的,
这是个人理解,希望能有大神给出比较有力的解释
Child Hello
Child Hello
- 下面程序的输出结果
public static void main(String[] args) {
int count = 0 ;
for (int i = 0; i < 10; i++) {
count = count ++;
}
System.out.println(count);
}
0 // 分析 额为加一个变量来看,a = count ++; 执行完成后 a = 0 ; count = 1 ;
同理此时将a 换成 count ,那count = 0 ;故无论执行多少次,count 总是0
查看javac编译后的源码即可明白
源码 | 编译后
int a = 0 ; | int a = 0;
a = a ++ ; | byte var10000 = a; --> a是0
| int var2 = a + 1;
| a = var10000; --> a 还是0
---------------------------------------------------
int a = 0 ; | int a = 0;
a ++ ; | int a = a + 1;