1-执行顺序优先级优先级:[静态程序块,静态成员】>[非静态程序块,非静态成员]>对象成员变量的构造函数>对象构造函数
变量的优先级>方法的优先级
静态>非静态的
块和成员变量的顺序按照代码的先后顺序
实质是先调用默认构造方法,然后执行隐式的super()或者this回归去父类,此时构造函数的方法体被暂停执行。
然后父类的一切执行完之后,返回子类,先完成代码块和成员变量初始化,再进行构造函数方法体
public class Person {
public Person(int id) {
System.out.println("person(" + id + ")");
}
public static void main(String[] args) {
Build b = new Build();
}
}
class Build {
Person p1 = new Person(1);
public Build() {
System.out.println("this is build's block!");
Person p2 = new Person(2);
}
Person p3 = new Person(3);
}
此处我主要想说明,用构造器创建类和变量的初始化顺序,该程序输出:
person(1)
person(3)
this is build’s block!
person(2)
说明:不论变量放在哪儿,都会先于任意一个方法的执行前执行,包括构造方法,而构造方法是一个类必须会执行的方法,不需要显示的进行调用。同时,不论变量在哪儿分布,只要在方法外部,就一定先于方法初始化。
public class Person {
public Person(int id) {
System.out.println("person(" + id + ")");
}
}
class Build {
/*静态块*/
static{
System.out.println("this is static block!");
}
/*非静态块*/
{
System.out.println("this is non-static block!");
}
static Person p1 = new Person(1);//------------1-----------
public Build() {
System.out.println("this is build's block!");
Person p2 = new Person(2);
}
Person p3 = new Person(3);
public static void main(String[] args) {
Build b = new Build();
}
}
this is static block!
person(1)
this is non-static block!
person(3)
this is build’s block!
person(2)
Class A{
A(){cout<<"A.A Called"}
A(int i){this(); cout<<"A.A(int) Called"}
}
Class B{
int i=f();
int j;
{
j=37;
Cout<<"Block executed"
}
B(){
this(10);
cout<<"B.B() called"
}
B(int i){
super(i);
cout<<"B.B(int) called";
}
int f(){
cout<<"B.f() called";
return 37;
}
Static{
Cout<<" Static Block executed"
}
}
主函数:
B b=new B();
- 调用构造方法B(),执行其中的super()或者this(),不执行真正方法体。 此时需要执行this(10),跳转到B(int i)构造方法中
- 调用构造方法B(int i),执行其中的super()或者this(),不执行真正方法体。此时需要执行super(i),跳转到父类的A(int i)构造方法中
- 调用构造方法A(int i),执行其中的super()或者this(),不执行真正方法体。此时需要执行this(),跳转到A()构造方法中
- 调用构造方法A(),执行其中的super()或者this(),不执行真正方法体。此时没有父类了,预备执行A()方法体之前,执行成员变量和代码块。
- A中没有成员变量,该步骤执行完毕
- 执行A()的方法体,输出“A.A called”
- 执行A(int i)的方法体 ,输出“A.A(int) called”
- 回归到子类B中,预备执行构造方法方法体之前,执行成员变量和代码块
- [静态]>非静态。输出” Static Block executed”
- B.i初始化,输出“”B.f() called””
- j初始化
- 代码块输出” Block executed”
- 执行B(int i)的方法体,输出”B.B(int) called”
- 执行B()的方法体,输出”B.B() called”
2-Static的作用
- Static作用于代码块:
称作静态代码块(可以初始化static field,不能初始化非static field;初始化只在类装载的时候执行一次。 - Static作用于methods
- Static方法只能访问static 方法,不能访问非static 方法
- Static 方法只能访问static field, 不能访问非static field
- 非static 方法可以访问static fields 和 static methods
- Static method的两种访问方式oject.method class.method, 非static method只有object.method一种访问方式
- Static method中不支持this和super
- 当一个方法前面的修饰符为private 或 static时,系统会自动在方法前面加一个final,所以该方法可以被继承但不能被重写。
- Static 不可以作为局部变量(局部变量包括:函数级局部变量和块级局部变量)
- Static作用于变量
- 不在对象的内存中占有空间,而是多个对象共享一个空间。
- 多个实例对象共享,可以改变
- 初始化只在类装载的时候执行一次。
- -
3-final的作用
final类不能被继承,没有子类,final类中的方法默认是final的。
final方法不能被子类的方法覆盖,但可以被继承。
final成员变量表示常量,只能被赋值一次,赋值后值不再改变。java允许将数据成员声明为final,却不赋初值。但是,blank finals必须在使用之前初始化,且必须在构造函数中初始化
final不能用于修饰构造方法。
注意:父类的private成员方法是不能被子类方法覆盖的,因此private类型的方法默认是final类型的。
public class sa {
final int i; //1、允许
public sa(int x) {
this.i=x; //2、必须有这句话,不然不能编译
}
public void doSomething() {
final int cc;
System.out.println( i);
// System.out.println( cc); //3、该处会抱错,因为cc未初始化
}
}
4-final static的作用
- 对于变量,表示一旦给值就不可修改,并且通过类名可以访问。
- 对于方法,表示不可覆盖,并且可以通过类名直接访问。
- 对于被static和final修饰过的实例常量,实例本身不能再改变了,但对于一些容器类型(比如,ArrayList、HashMap)的实例变量,不可以改变容器变量本身,但可以修改容器中存放的对象,这一点在编程中用到很多。
5-Abstract修饰符
public class B extends A {
@Override
void a() {
System.out.println();
}
}
abstract class A {
abstract void a();
void b(){
}
}
- Abstract class该类不能实例化对象
- Abstract class该类可以不包含abstract method,但是只要有一个abstract method那么该类必须为abstract class
- Abstract method 该方法没有方法体,需要被override
- Abstract class的子类要么实现其父类全部的abstract method,要么也是一个abstract class
- Abstract 不能修饰 field
- Abstract不能修饰局部变量(方法级局部变量(形参级局部变量,方法体级局部变量)或块级局部变量)
6-interface[java]
声明为interface的类为接口,比抽象类更加抽象的一种机制。在接口中,我们不能提供任何实现,所有方法必须都是抽象的,可以不加abstract关键字,但是编译器对于接口中的方法,都是直接按抽象方法处理的。
7-static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?[C++中]
全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。
static函数与普通函数作用域不同。static函数仅在本文件中使用。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件
static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用;
static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;
static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝