Static
1、
public class Cat extends Animal{
static{//static 在main方法之前执行,会先加载static
System.out.println("2");
}
public Cat(){
System.out.println("4");
}
public static void main(String[] args){
//new Animal(); //这样不会创建子类的对象
new Cat();//会先执行父类,因为子类可能重写,所以必须先加载父类
}
}
class Animal{
static{//
System.out.println("1");
}
Animal(){
System.out.println("3");
}
}
执行输出1 2 3 4
思路:看到代码,发现有继承,发现父类中有static 修饰块,先加载,再加载子类中static块,static 在main方法之前执行,加载完static之后看main方法,创建对象,先加载父类中的方法,因为子类可能会重写,再加载子类中的方法,按照1 2 3 4顺序执行。
2、
public class Demo {
public Demo(String aa){
System.out.println(""+aa);
}
static {
System.out.println("1");
}
public static Demo demo = new Demo("2");
static {
System.out.println("3");
}
}
//会寻找main方法执行,Test中main方法之前没有static块
class Test{
public static void main(String[] args) {
Demo demo = new Demo("4");
}
}
执行输出 1 2 3 4
寻找main方法,new Demo()创建对象,开始加载Demo类,注意类只会加载一遍,Demo中的现在先加载static,因为有3个static关键字修饰的,按照顺序加载,加载 public static Demo demo = new Demo(“2”); 时,不需要从头重新执行一遍,只需要加载构造器public Demo(String aa)就可以,因为类只会加载一遍。按照顺序
1 2 3 4执行
值传递在内存中表现
1、
public class Student {
private String name;
private int age;
public Student(String name,int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
public static void change(Student s1, Student s2){
Student temp = new Student("王五",20);
temp = s1;
s1 = s2;
s2 = temp;
}
public static void main(String[] args) {
Student zhangsan = new Student("张三", 18);
Student lisi = new Student("李四", 20);
Student.change(zhangsan, lisi);
System.out.println(zhangsan.toString());
System.out.println(lisi.toString());
}
}
输出结果依旧是 张三 18 李四 20,因为java中是值传递,将地址传去,所以执行change()方法时里面地址交换,弹出栈之后,原来的内容没有改变
2、
public class Student {
private String name;
private int age;
public Student(String name,int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
public static void change(Student s1, Student s2){
Student temp = new Student("王五",20);
temp.name = s1.name;
s1.name = s2.name;
s2.name = temp.name;
}
public static void main(String[] args) {
Student zhangsan = new Student("张三", 18);
Student lisi = new Student("李四", 20);
Student.change(zhangsan, lisi);
System.out.println(zhangsan.toString());
System.out.println(lisi.toString());
}
}
输出结果 张三 20 李四 18,因为change()方法不仅传了地址,还将里面的只改变了,就像拿着钥匙打开门改变了家里布局,钥匙没变,家里改变了。
3、
class Two{
Byte x;
}
public class Student {
public static void main(String[] args) {
Student student = new Student();
student.start();
}
void start() {
Two two = new Two();
System.out.print(two.x +" ");
Two two2 = fix(two);
System.out.println(two.x + " "+two2.x);
}
Two fix(Two tt) {
tt.x = 42;
return tt;
}
}
输出结果 null 42 42 因为Byte中B为大写,是包装类,没有值是null而不是0,其他结果如图所示可以得出