satic修饰属性:无论一个类生成了多少个对象,所有这些对象共同使用唯一一份静态的成员变量,;一个对象对给静态成员变量进行了修改,其他对象的该静态成员变量的值也会随之发生变化。如果一个成员变量是static的,那么我们可以通过类名.成员变量名的方式来使用它(推荐使用)。
|
2、static修饰方法:static修饰的方法叫做静态方法。对于静态方法来说,可以使用类名.方法名的方式来访问,并且推荐使用这种使用方法
public class StaticTest2
{
public static void main(String[] args)
{
//MyStatic1 t = new MyStatic1();
//t.output();
MyStatic1.output();
//直接使用类名.方法名的方式,推荐使用
}
}
class MyStatic1
{
public static void output()
{
System.out.println("output");
}
}
3、关于静态方法继承的问题。
public class StaticTest3
{
public static void main(String[] args)
{
M m = new N();
m.output();
//结果为M,而不是N,需要注意
//对于static方法,继承只会隐藏父类方法,而不是重写
//调用哪个方法主要看引用变量的类型
N n = new N();
n.output();//结果为N
class M
{
public static void output()
{
System.out.println("M");
}
}
class N extends M
{
public static void output()
{
ystem.out.println("N");
}
}
静态方法只能继承,不能重写(override)
4、final关键字:final可以修饰属性、方法、类。
A) final修饰类:当一个类被final所修饰,表示该类是个终态类,不能被继承。
final class Test
{
}
则该Test类不能被继承
class Test1 extends Test错误
B)final修饰方法:当一个方法被fianl所修饰时,表示该方法是一个终态方法,不能被重写(override)
C)fianal修饰属性:当一个属性被final所修饰时,表示该属性不能被改写。
当fianl修饰一个原生数据类型时,表示改原生数据类型的值不能发生变化(比如说不能从10变为20);如果fianl修饰一个引用类型时,表示该引用类型不能再指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。
public class FinalTest
{
public static void main(String[] args)
{
People people = new People();
people.age = 20; //错误,final类型的属性不能被改变
people.address = new Address();//错误
//fianl修饰一个引用类型时,表示该引用类型不能再指向其他对象了,这里new Address()表示一个新的对象
people.address.name = "shanghai";//正确,引用所指向的对象的内容是可以发生变化的
}
}
class People
{
final int age = 10;
final Address address = new Address();
}
class Address
{
String name = "beijing";
}
5、对于final类型的成员变量,一般来说有两种赋初值方式:
A)在声明final类型的成员变量时就赋上初值
B)在声明final类型的成员变量时不赋初值,但在类的所有构造方法中都为其赋上初值
public class FinalTest2
{
final int a;
}
//上例错误
public class FinalTest2
{
final int a = 0;
}
//上例正确
public class FinalTest2
{
final int a;
public FinalTest2()
{
a = 0;
}
}
//上例正确
public class FinalTest2
{
final int a;
public FinalTest2()
{
a = 0;
}
public FinalTest2(int a)
{
}
}
//上例错误
6、static代码块:静态代码块
public
class
StaticTest4
{
public
static
void
main(String[] args)
{
P p =
new S
();
}
}
class
P
{
static
{
System.out.println(
"P static"
);
}
public
P()
{
System.out.println(
"P constructor"
);
}
}
class
Q
extends
P
{
static
{
System.out.println(
" Q static"
);
}
public
Q()
{
System.out.println(
"Q constructor"
);
}
}
class
S
extends
Q
{
static
{
System.out.println(
" S static"
);
}
public
S()
{
System.out.println(
"S constructor"
);
}
}
|
执行结果
P static
Q static
S static
P constructor
Q constructor
S constructor
如果主程序是这样的:
new S();
new S();
则结果:
P static
Q static
S static
P constructor
Q constructor
S constructor
P constructor
Q constructor
S constructor
总结:1)静态代码块。作用也是完成一些初始化工作。首先执行静态代码块,然后执行构造方法。静态代码块在类被加载的时候执行,而构造方法是在生成对象的时候执行(所以先打印静态代码块数据);想要调用某个类来生成对象,首先需要将类加载到java虚拟机上(jvm),然后由jvm加载这个类来生成对象。
2)类的静态代码块只会执行一次,是在类被加载的时候执的,因为每个类只会被加载一次,所以静态代码块也只会被执行一次;而构造方法则不然,每次生成一个对象的时候都会调用类的构造方法,所以new一次就会调用构造方法一次。
3)如果继承体系中既有构造方法,又有静态代码块,那么首先执行最顶层的类的静态代码块,一直
执行到最底层类的静态代码块,然后再去执行最顶层类的构造方法,一直执行到最底层类的构造方法。注意:静态代码块只会执行一次。
7、不能在静态方法中访问非静态成员变量;可以在静态方法中访问静态的成员变量。可以在非静态方法中访问静态的成员变量
public class StaticTest5
{
public static void main(String[] args)
{
W.change();
}
}
class W
{
int a = 10; //如果改成:static int a = 10;则正确
public static void change()
{
a++; //错误
}
}
以上代码错误,不能在静态的方法中访问非静态成员变量。
总结:静态的只能访问静态的;非静态的可以访问一切。
8、不能在静态方法中使用this关键字。
9、接口中所声明的方法都是抽象方法。接口中的方法都是public的;接口中也可以定义成员变量。接口中的成员变量都是public、final、static的
public interface Interface1
{
int a = 1; //相当于public final static int a = 1;
}
10、一个类不能既是final又是abstract的。因为abstract的主要目的是定义一种约定,让子类去实现这种约定,而final表示该类不能被继承,这样abstract希望该类可以被继承而final明确说明该类不能被继承,两者矛盾。因此一个类不能既是final的又是abstract的。