简介
- 本文是2021/04/01整理的笔记
- 赘述可能有点多,还请各位朋友耐心阅读
- 本人的内容和答案不一定是最好最正确的,欢迎各位朋友评论区指正改进
代码的执行顺序:
- 父类静态代码块 - 子类静态代码块 - 父类初始化代码块- 父类构造方法-子类初始化代码块- 子类构造方法
- 代码示例
public class Father {
public Father() {
System.out.println("父类无参构造方法执行");
}
static {
System.out.println("父类静态代码块执行");
}
{
System.out.println("父类初始化代码块执行");
}
}
public class Son extends Father{
public Son() {
System.out.println("子类无参构造方法执行");
}
static {
System.out.println("子类静态代码块执行");
}
{
System.out.println("子类初始化代码块执行");
}
}
public class TestMain {
public static void main(String[] args) {
Son son = new Son();
}
}
程序运行结果
父类静态代码块执行
子类静态代码块执行
父类初始化代码块执行
父类无参构造方法执行
子类初始化代码块执行
子类无参构造方法执行
易错练习题
第1题
class Super{
public static void m1(){
System.out.println("m1 in Super");
}
public void m2(){
System.out.println("m2 in Super");
}
}
class Sub extends Super{
public static void m1(){
System.out.println("m1 in Sub");
}
public void m2(){
System.out.println("m2 in Sub");
}
}
public class TestMain{
public static void main(String args[]){
Super sup = new Sub();
sup.m1();
sup.m2();
Sub sub = (Sub) sup;
sub.m1();
sub.m2();
}
}
题目1:读程序,写结果
答案:
m1 in Super
m2 in Sub
m1 in Sub
m2 in Sub
解析:statci修饰的方法属于类。
即静态方法看编译期类型,等号左侧
第2题
class MyClass {
public void printValue(final int value){
System.out.println(value);
}
public void changeValue(int value){
value = value * 2;
System.out.println(value);
}
}
public class TestMain{
public static void main(String args[]){
MyClass mc = new MyClass();
int value = 5;
final int fvalue = 10;
mc.printValue(value); //1
mc.printValue(fvalue); //2
mc.changeValue(value); //3
mc.changeValue(fvalue);//4
}
}
题目2:选择正确答案
A. 编译通过
B. //1 出错
C. //2 出错
D. //3 出错
E. //4 出错
答案: A
解析:最容易误解的地方是mc.changgevalue(fvalue)这一句
Java中向方法中传参的方式是值传递,我们传入的fvalue其实是一个副本,副本是可以改变的,不会影响到fvalue的值。
第3题
abstract class MyAbstractClass{
public abstract void m1(); //1
abstract protected void m2(){
} //2
}
class MySubClass extends MyAbstractClass{
void m1(){
} //3
protected void m2(){
} //4
}
问:这段代码哪些地方有错误?
A. //1
B. //2
C. //3
D. //4
答:BC
解析:
第二行,abstract方法没有方法体
第三行,子类重写的方法的权限修饰符要大于等于父类的
第4题
class ClassA{
static {
System.out.println("In ClassA Static");
}
public ClassA(){
System.out.println("ClassA()");
}
}
class ClassB{
static {
System.out.println("In ClassB Static");
}
public ClassB(){
System.out.println("ClassB()");
}
}
class ClassC extends ClassB{
static{
System.out.println("In ClassC Static");
}
public ClassC(){
System.out.println("ClassC()");
}
}
class MyClass {
static ClassA ca = new ClassA();
ClassC cc = new ClassC();
static{
System.out.println("In MyClass Static");
}
public MyClass(){
System.out.println("MyClass()");
}
}
public class TestMain{
public static void main(String args[]){
MyClass mc1 = new MyClass();
MyClass mc2 = new MyClass();
System.out.println(mc1.cc == mc2.cc);
System.out.println(mc1.ca == mc2.ca);
}
}
题目4:读程序,写结果
答案:
(1)In ClassA Static
(2)ClassA()
(3)In MyClass Static
(4)In ClassB Static
(5)In ClassC Static
(6)ClassB()
(7)ClassC()
(8)MyClass()
(9)ClassB()
(10)ClassC()
(11)MyClass()
(12)false
(13)true
解析:
- 创建mc1对象,先执行Myclass中的静态部分
- static ClassA ca = new ClassA();
- 执行ClassA中的静态部分,即 (1)In ClassA Static
- 再执行ClassA中的无参构造方法,即(2)ClassA()
- 执行MyClass中的静态代码块 (3)In MyClass Static
- 静态部分执行完毕,开始执行非静态部分
- Class cc = new ClassC()
- 先执行父类的静态部分,再执行子类的静态部分。即(4)In ClassB Static (5)In ClassC Static
- 然后执行子类中的构造方法,子类的构造方法隐含了一句话:super();
- 然后执行 父类中的构造方法,即(6) ClassB()
- 然后执行子类的构造方法,即(7)ClassC()
- Class cc =new ClassC( )执行完毕,(8)输出MyClass( )
- 创建mc2对象,此时静态部分不再执行,因为静态部分只执行一次
- 所以我们执行Class cc = new ClassC( )
- 还是先执行(9)ClassB() 然后执行(10)ClassC()
- 然后执行MyClass()
- 由于cc是非静态的对象,创建了两次,地址不同false
- 由于ca是静态对象,共享,地址相同true