1. 变量被final修饰后不能再指向其他对象,但可以重写
如果是引用变量被final修饰,那么的确如此;
基本变量不能重写
2. 下列代码的输出结果是?
public class Test {static {int x = 5; }static int x,y; public static void main(String[] args) {x--; myMethod();System.out.println(x+y+ ++x);}public static void myMethod() {y = x++ + ++x;}}
答案:3
解析:
静态代码块的变量属于局部变量,这里的5,代码块结束就会销毁
static {int x = 5; }
static int x,y; // 全局基本类型的变量,默认值0
public static void main(String[] args) {x--; myMethod();System.out.println(x+y+ ++x);}public static void myMethod() {y = x++ + ++x;}
x–变成-1
myMethod方法,x++的自增在两个x之间的+运行之后才会执行,所以y = -1+1 = 0
最后打印的结果1+0+2 = 3
3.下面哪些赋值语句是正确的?
A:long text = 012;
B:float t = -412;
C:int other = (int) true;
D:double d = 0x12345678;
E:byte b = 128;
答案:A,B,D
A正确,因为0开头的数字代表8进制数字,,010转化成是十进制就是8
B,小一点的int转float不会出错,大int转float会出错,因为float有效位数只有23位,不足以全部容纳32位的int
D,任何int转double不会出错,因为double的有效位数是53位,足够容纳全部的int
4. 下列程序的执行结果?
class Base {public Base(String s) {System.out.println("B");}
}
public class Dervid extends Base {public Dervid(String s) {System.out.println("D");}public static void main(String[] args) {System.out.println("C");}
}
A: BD
B: DB
C: C
D: 编译错误
答案是D
java当中,我们都知道一个规则,就是子类执行构造方法时,必须执行父类的同样结构的构造方法,这是由于继承的成员复用导致的
前置知识1
继承的成员复用(成员变量和成员方法可以传递给子类使用),由多个对象创建并功能叠加实现的
A类是父类,B类是A类的子类
我们可以看到,B类的对象当中同时存在了A类的对象+B类的对象,所以子类构造方法的调用必然会静默调用父类的构造方法
前置知识2
当父类和子类都没有重载构造方法的时候,java会默认使用super()关键字实现前置知识1里面的机制
public class A {
}
public class B extends A{public static void main(String[] args) {B b = new B();}
}
java帮我们自动实现了无参构造
上面的代码其实隐含了一些代码执行
public class A {public A(){}
}
public class B extends A{public static void main(String[] args) {B b = new B();}// java帮我们自动创建无参构造,只有在无参构造当中才会自动追加一个super()执行父类的无参构造public B(){super();}
}
但是我们一旦给父类创建了有参构造,去代替无参构造,子类的构造方法不会自动追加super(),此时子类的所有构造方法都需要程序员手动执行super(父类有参构造参数),也就是说此时子类不可能再有无参构造
public class A {public Integer i;public A(Integer i) {this.i = i;}
}
public class B extends A {public String t;// 父类成员变量形参+子类成员变量形参public B(Integer i, String t) {super(i);this.t = t;}// 至少得包含父类的Integer变量作为构造形参public B(Integer i) {super(i);}public static void main(String[] args) {B b = new B(1);}
}
现在我们回到题目
显然Dervid类作为子类,至少得包含父类的String s成员变量,并且需要显式的调用super(s);
这样才不会报错
如果此时父类追加一个无参构造
public class A {public Integer i;public A(Integer i) {this.i = i;}public A() {}
}
这样B类就可以有无参构造了
5.关于final关键字下列说法正确的是
A:如果修饰局部变量必须初始化
B:如果修饰类,则该类只能被一个子类继承
C:如果修饰方法,则该方法不能在子类当中重写
D:如果修饰方法,则该方法所在的类不能被继承
答案:C
final修饰局部变量不需要初始化,只需要在用到这个变量之前初始化即可,因为局部变量的使用范围仅在代码块内部,外部无法访问;
但是修饰成员变量必须直接初始化/构造方法间接初始化,因为这是全局变量,所有的代码都能访问到它,为了防止值被修改,在创建时就要赋值
或者构造方法初始化
如果这个全局变量是static的,那么只有直接初始化一条路可以走
因为static变量无法在非静态的方法中使用,构造方法全都是非静态的
此时有人会问,那static+final修饰的局部变量呢?
不好意思,static不能修饰局部变量
因为static是类共享的,局部变量不可能类共享,两者冲突
6. 下列代码运行的结果是
public class DemoTest {public static void main(String[] args) {String s;System.out.println("hello" + s);}
}
A:在控制台打印hello
B:报异常java.lang.NullPointException
C:编译报错
D:报异常java.RuntimeException
答案:C
很多人会说,因为这里s对象是null,其实不是的
s对象是null是不会编译错误的
真正错误的原因是s对象没有初始化,甚至连null都不是
如果初始化赋值null,就不会报错
局部变量不会自动初始化,但是全局的成员变量可以自动初始化为null