静态对象
- 静态对象的数据是全局唯一的,一改全改。
- 引用方便。直接用 类名. 静态方法名 或者 类名 . 静态变量名 就可以直接应用并可以直接修改其值,不需要 get 和 set 方法。
- 保持数据的唯一性,修改他的任意一处地方,其他所使用到的地方都将随之改变。有效减少多余的浪费。
- static 和 final 用来修饰成员变量和成员方法,可简单理解为“全局常量”。对于变量一旦给值便不能被更该,对于方法表示不可覆盖。
静态变量、静态方法、静态块
- 通常情况,类成员必须通过类的实例来访问,但是在成员声明前面加上 static 关键字就能创建一个不需引用任何对象,可直接通过类访问。可以将变量和方法都设置为 static ,最常见的例子便是 main() 函数。声明为 static 的方法有以下几条限制:
- 仅能调用其他的 static 方法
- 仅能访问 static 数据
- 不能以任何的方式引入 this、super(this) 涉及到对象,super 与继承有关
- 示例:Static 块仅在该类被加载时执行一次。下面的例子显示的类有一个static方法,一些static变量,以及一个static 初始化块。
public class TestNew {
static int a = 3;
static int b;
static void meth(int x){
System.out.println("x = "+x);
System.out.println("a = "+a);
System.out.println("b = "+b);
}
static {
System.out.println("static block initialized");
b = a*4;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
meth(42);
}
}
执行结果是:
static block initialized
x = 42
a = 3
b = 12
上述class TestNew的执行顺序是:首先static 块执行(打印一条消息),a被设置为3,最后b被初始化为a*4 成12。然后调用main(),main () 调用meth() ,把值42传递给x。3个println ( ) 语句引用两个static变量a和b,以及局部变量x 。
外部使用静态方法或静态变量
- 在定义它们的类的外面,static 方法和变量都能独立于任何对象而被使用,只要在类的名字后加点号运算符即可。示例:
class StaticDemo{
static int a = 42;
static int b = 99;
static void callme(){
System.out.println("a = "+a);
}
}
public class TestNew {
public static void main(String[] args) {
// TODO Auto-generated method stub
StaticDemo.callme();
System.out.println("b = "+StaticDemo.b);
}
}
执行结果:
a = 42
b = 99
静态内部类
指在一个类的内部,再用 static 修饰一个类。用静态内部类是因为与外部内有一定的关系,只有在外部类调用内部类,因此没有必要专门用一个Java文件放这个类。但是在在编译成功后,会出现这样两个 class 文件: OuterClass.class和OuterClass$InnerClass.class。
静态方法、静态成员变量,它唯一的作用就是随着类的加载(而不是随着对象的产生)而产生,以致可以用类名+静态成员名直接获得。这样静态内部类就可以理解了,它可以直接被用外部类名+内部类名获得(只针对内部类的静态成员,非静态成员必须内部类实例对象访问)。
public class OuterClass{
private String out_str1 = "外部类非静态成员";
private static String out_str2 = "外部类静态成员";
public static class InnerClass{
private static String str = "Java学习";
public String str1 = "静态内部类学习";
public void display1(){
System.out.println(out_str2);//直接访问外部类的静态成员
}
public static void display2(){
// System.out.println(out_str1);//不能直接访问外部类的非静态成员
}
}
public void printInfo(){
System.out.println(OutClass.InnerClass.str); //直接访问内部类静态成员
InnerClass inner = new InnerClass();//访问静态内部类非静态成员必须实例化
System.out.println(inner.str1);
inner.display1();
}
public static void main(String[] args) {
OutClass out = new OutClass();
out.printInfo();
}
}
- 在静态内部类不能访问外部类的非静态成员,这是由Java语法中"静态方法不能直接访问非静态成员"所限定。若想访问外部类的变量,必须通过其它方法解决,由于这个原因,静态嵌套类使用很少。注意,外部类访问内部类的的成员有些特别,不能直接访问非静态成员,但可以通过内部类来访问,对于内部类静态成员可以直接用外部类名+内部类名获得。同时注意,内部静态类 InnerClass 只在外部类 OutClass 范围内可见,若在其它类中引用或初始化,均是错误的。
非静态内部类
- 如下所示代码为在外部类中定义两个内部类及它们的调用关系:
public class Outer {
int outer_x = 100;
class Inner{
public int y = 10;
private int z = 9;
int m = 5;
public void display(){
System.out.println("display outer_x:"+ outer_x);
}
private void display2(){
System.out.println("display outer_x:"+ outer_x);
}
}
void test(){
Inner inner = new Inner();
inner.display();
inner.display2();
//System.out.println("Inner y:" + y);//不能访问内部内变量
System.out.println("Inner y:" + inner.y);//可以访问
System.out.println("Inner z:" + inner.z);//可以访问
System.out.println("Inner m:" + inner.m);//可以访问
InnerTwo innerTwo = new InnerTwo();
innerTwo.show();
}
class InnerTwo{
Inner innerx = new Inner();
public void show(){
//System.out.println(y);//不可访问Innter的y成员
//System.out.println(Inner.y);//不可直接访问Inner的任何成员和方法
innerx.display();//可以访问
innerx.display2();//可以访问
System.out.println(innerx.y);//可以访问
System.out.println(innerx.z);//可以访问
System.out.println(innerx.m);//可以访问
}
}
public static void main(String args[]){
Outer outer = new Outer();
outer.test();
}
}
- 以上代码需要说明有,对于内部类,通常在定义类的class关键字前不加public 或 private等限制符,若加了没有任何影响,同时好像这些限定符对内部类的变量和方法也没有影响(?)。另外,就是要注意,内部类Inner及InnterTwo只在类Outer的作用域内是可知的,如果类Outer外的任何代码尝试初始化类Inner或使用它,编译就不会通过。同时,内部类的变量成员只在内部内内部可见,若外部类或同层次的内部类需要访问,需采用示例程序中的方法,不可直接访问内部类的变量。