Java static 静态变量、方法、块,(非)静态内部类

静态对象

  1. 静态对象的数据是全局唯一的,一改全改。
  2. 引用方便。直接用 类名. 静态方法名 或者 类名 . 静态变量名 就可以直接应用并可以直接修改其值,不需要 getset 方法。
  3. 保持数据的唯一性,修改他的任意一处地方,其他所使用到的地方都将随之改变。有效减少多余的浪费。
  4. static 和 final 用来修饰成员变量和成员方法,可简单理解为“全局常量”。对于变量一旦给值便不能被更该,对于方法表示不可覆盖。

静态变量、静态方法、静态块

  1. 通常情况,类成员必须通过类的实例来访问,但是在成员声明前面加上 static 关键字就能创建一个不需引用任何对象,可直接通过类访问。可以将变量和方法都设置为 static ,最常见的例子便是 main() 函数。声明为 static 的方法有以下几条限制:
  • 仅能调用其他的 static 方法
  • 仅能访问 static 数据
  • 不能以任何的方式引入 thissuper(this) 涉及到对象,super 与继承有关
  1. 示例: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*412。然后调用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

静态内部类

  1. 指在一个类的内部,再用 static 修饰一个类。用静态内部类是因为与外部内有一定的关系,只有在外部类调用内部类,因此没有必要专门用一个Java文件放这个类。但是在在编译成功后,会出现这样两个 class 文件: OuterClass.class和OuterClass$InnerClass.class。

  2. 静态方法、静态成员变量,它唯一的作用就是随着类的加载(而不是随着对象的产生)而产生,以致可以用类名+静态成员名直接获得。这样静态内部类就可以理解了,它可以直接被用外部类名+内部类名获得(只针对内部类的静态成员,非静态成员必须内部类实例对象访问)。

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();
         
     }
}
  1. 在静态内部类不能访问外部类的非静态成员,这是由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或使用它,编译就不会通过。同时,内部类的变量成员只在内部内内部可见,若外部类或同层次的内部类需要访问,需采用示例程序中的方法,不可直接访问内部类的变量。


作者:Yanci516
链接:https://www.jianshu.com/p/8cb87b7177ef
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

猜你喜欢

转载自blog.csdn.net/youyou_go/article/details/80921831