一:关于静态代码块,匿名代码块,构造器的执行顺序
当子类继承父类,子类创建一个实例化对象的时候,里面的代码块执行顺序
public class Test {
public static void main(String[] args) {
Son s = new Son();
System.out.println("-------------------");
Son s1 = new Son("1");
}
}
class Son extends Father{
private String name;
static {
System.out.println("我是son的静态代码块");
}
{
System.out.println("我是son的匿名代码块");
}
public Son(){
hh();
System.out.println("我是son的无参构造器");
}
public Son(String name) {
this.name = name;
hh();
System.out.println("我是son的有参构造器");
}
public void hh() {
System.out.println("我是son的普通代码块");
}
}
class Father {
private String name;
static {
System.out.println("我是father的静态代码块");
}
public Father() {
hh();
System.out.println("我是father的无参构造器");
}
{
System.out.println("我是father的匿名代码块");
}
public Father(String name) {
this.name = name;
System.out.println("我是father的有参构造器");
}
public void hh() {
System.out.println("我是father的普通代码块");
}
}
从上面代码运行结果可以得出三个结论:
第一:静态代码块是在类加载的时候执行的
第二:匿名代码块这种代码块是会在调用构造器的时候,一起执行且在构造器之前执行
第三:普通的代码块在匿名代码块后面,在构造器中的输出顺序取决于你书写的顺序
二:多态
编译时多态也就是说的方法的重载,就不多说了~
这里说的是运行时多态,主要指的是java变量在运行期间,所引用的类型会因为它最终所指向的对象的不同,而有不同的状态,多态发生在对方法的重写,不同的对象对于父类的方法的重写。
举个例子,看如下代码的效果:
public class Test {
public static void main(String[] args) {
Animal a = new Bird();
Animal b = new Dog();
a.run();
b.run();
}
}
class Animal {
public void run() {
System.out.println("我是动物的运动方式");
}
}
class Bird extends Animal {
public void run() {
System.out.println("我是鸟,我用飞的");
}
}
class Dog extends Animal {
public void run() {
System.out.println("我是狗,我用跑的");
}
}
运行结果如下
我们可以看出,虽然变量的引用类型都是Animal类型,但是因为它们所指向的对象不同而表现的形式而有所不同。java在编译阶段中能调用什么方法取决于他们的引用类型,在语法上限制能调用什么类型的方法,不然会出现语法上的混乱,比如说下面的例子:
public class Test {
public static void main(String[] args) {
Bird b = new Bird();
Animal a = new Bird();
Test t = new Test();
t.test(a);
}
public void test(Animal a) {
//这句话报错,因为Animal类型,它所指向的对象,你不能确定子类下面是否有这个方法,指向哪个子类
a.body();
}
}
class Animal {
public void run() {
System.out.println("我是动物的运动方式");
}
}
class Bird extends Animal {
public void run() {
System.out.println("我是鸟,我用飞的");
}
public void body(Animal a) {
System.out.println("我有一双翅膀");
}
}
class Dog extends Animal {
public void run() {
System.out.println("我是狗,我用跑的");
}
}
从上面代码可以看出,当你传入的参数是父类型的时候,有的子类有body方法,而有的子类没有,这时候就会出现语法上面的错误,所以为了避免这种错误,在java编译的期间规定能调用什么方法是取决于它的引用类型,而最终运行的时候,jvm调用什么样的方法会具体看它指向的对象决定的。
三:类型转换
关于类型转换的话,注意一下面试可能考的点吧…
byte x = 1;
byte y = 1;
int z = x + y; //+号会使结果转为int类型
两个变量相加,先对类型进行提升,然后运算,再将运算结果赋值 两个byte类型相加的值可能超过byte的取值范围
两个常量相加 先计算常量数值,然后判断是否满足类型范围,再赋值