zoukankan      html  css  js  c++  java
  • static静态关键字

    转载自大佬:https://www.cnblogs.com/xrq730/p/4820992.html

    静态资源和静态方法

    首先,静态的资源和方法等会随着类的加载而进入内存被初始化,而非静态的资源和方法会随着new的动作被初始化。即,静态先,非静态后。

    由于这种特性,我们可以理解static的基本用法:

    1、被static修饰的变量属于类变量,可以通过类名.变量名直接引用,而不需要new出一个类来

    2、被static修饰的方法属于类方法,可以通过类名.方法名直接引用,而不需要new出一个类来

    被static所修饰的变量是唯一的静态资源,是各个对象实例化后所共享的资源,则静态资源被改变后,所有实例中的该资源都会改变。

    下面来理解一个问题:静态方法能不能调用非静态资源?以下面代码为例

    public class A
    {
        private int i = 1;
        
        public static void main(String[] args)
        {
            i = 1;
        }
    }

    main方法是静态方法,i是非静态资源。在类加载进入内存时,main方法初始化,方法中的所有资源都要被加载进内存。而由于i是非静态资源,要通过new来初始化,所以i并不能进入内存。

    所以我们可以得到以下结论:

      1,静态方法不能调用非静态资源

      2,静态方法可以调用静态资源

      3,非静态方法可以调用静态资源

    静态代码块

      静态块的语法如下

    static{
        statments;
        ........  
    }

    静态块是用于初始化一个类的时候同时进行一些操作的。静态块中的代码只在初始化类的时候执行一次。

    public class A
    {
        private static int a = B();
        
        static
        {
            System.out.println("Enter A.static block");
        }
        
        public static void main(String[] args)
        {
            new A();
        }
        
        public static int B()
        {
            System.out.println("Enter A.B()");
            return 1;
        }
    }

    打印结果:

    Enter A.B()
    Enter A.static block

    我们看到,在main方法中,首先new了对象A,按顺序加载a=B(),调用方法B,打印Enter A.B(); 然后打印静态块中的内容。

    可以得到结论:静态资源的加载顺序是严格按照静态资源的定义顺序来加载的

    再看一个例子:

    复制代码
     1 public class A
     2 {
     3     static
     4     {
     5         c = 3;
     6         System.out.println(c);
     7     }
     8     
     9     private static int c;
    10 }
    复制代码

    这段代码的第6行是有错误的“Cannot reference a field before it is defined”。从这个例子得出第二个结论:静态代码块对于定义在它之后的静态变量,可以赋值,但是不能访问

    最后一个小例子:

    复制代码
     1 public class A
     2 {
     3     static
     4     {
     5         System.out.println("A.static block");
     6     }
     7     
     8     public A()
     9     {
    10         System.out.println("A.constructor()");
    11     }
    12 }
    复制代码
    复制代码
     1 public class B extends A
     2 {
     3     static 
     4     {
     5         System.out.println("B.static block");
     6     }
     7     
     8     public B()
     9     {
    10         System.out.println("B.constructor()");
    11     }
    12     
    13     public static void main(String[] args)
    14     {
    15         new B();
    16         new B();
    17     }
    18 }
    复制代码

    结果是

    A.static block
    B.static block
    A.constructor()
    B.constructor()
    A.constructor()
    B.constructor()

    这个例子得出第三个结论:静态代码块是严格按照父类静态代码块->子类静态代码块的顺序加载的,且只加载一次

    static修饰类

    这个用得相对比前面的用法少多了,static一般情况下来说是不可以修饰类的,如果static要修饰一个类,说明这个类是一个静态内部类(注意static只能修饰一个内部类),也就是匿名内部类。像线程池ThreadPoolExecutor中的四种拒绝机制CallerRunsPolicy、AbortPolicy、DiscardPolicy、DiscardOldestPolicy就是静态内部类。静态内部类相关内容会在写内部类的时候专门讲到。    待补充

    import static

    这个比较冷门,基本很少看见有地方用,使用JUnit可能会用到,写assert的时候会方便些。import static是JDK1.5之后的新特性,这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名.资源名,可以直接使用资源名。注意一下,import static必须这么写,而不能写成static import。举个例子来看一下:

    package chapter3Demos;
    
    import static java.lang.System.out;
    
    import static java.lang.Math.*;
    
    public class Demo3_3_2 {
    
        public static void main(String[] args)  {
            out.println(sin(2.2));
        }
    }

    第一个import static表示直接指定导入out这个静态资源,可以省略写System,但是不能使用其他System类中的静态方法。

    第二个import static表示导入了Math类中所有的静态方法,不仅sin可以不写Math,其他数学函数也可以省略不写

    这种写法减少了代码量,简化了一些操作,但是降低了代码的可读性。

    除了在一些特定场合用到之外,建议不要使用。

  • 相关阅读:
    【JZOJ6271】【NOIP提高组A】锻造 (forging)
    【JZOJ6272】【NOIP提高组A】整除 (division)
    【JZOJ3397】【GDOI2014模拟】雨天的尾巴
    input绑定datapicker控件后input再绑定blur或者mouseout等问题
    解决每次打开office 2010显示正在配置的问题
    Ext JS treegrid 发生的在tree上增加itemclick 与在其它列上增加actioncolumn 发生事件冲突(event conflict)的解决办法
    Ext JS4 学习笔记之发送表单(Form)时也将表单下的表格(Grid)数据一同发送的方法
    本地同时启动两个tomcat
    转: ExtJS中xtype一览
    web前端基础知识及快速入门指南
  • 原文地址:https://www.cnblogs.com/Joey777210/p/11752144.html
Copyright © 2011-2022 走看看