java-static关键字

Static关键字

从问题方面了解static关键字的使用:

问题一:为什么要使用static关键字?什么情况下才使用static关键字?

  答:(1)一般情况,对象需要使用new来创建对象,数据存储空间才被分配,其类的变量或者方法供外界调用。

但上述方法,有两种情形是无法实现

  ①只为某特定区域分配单一存储空间,但不考虑创建多少对象,甚至不创建对象;

  ②没有创建对象,也能调用该对象的方法。

  static关键字可以解决上面的情况。

(2)静态变量

  静态变量的访问可以不创建对象, 直接用类名.静态变量”;也可以创建对象用对象名.静态变量访问静态变量。还可以通过改变对象名.静态变量来改变静态变量的值。

  问:可以通过类名.静态变量访问静态变量如:HelloWorld.className;也可以通过 对象名.静态变量访问静态变量。但是,什么也不加,直接className也可以呀?是因为有什么弊端吗?

  答:静态变量是可以直接引用的,不过是不安全的。在访问静态变量的时候首选类名.静态变量的方式,这不仅是因为它强调了变量的static的结构,而且在某些情况下它还为编译器进行优化提供了更好的机会

  因为main()前也有一个static关键字,这表明mian()是一个静态方法,而静态方法是可以直接访问静态变量的。你所谓的直接className是在一个类里面才行的通,出了这个类就报错。

public class TestStatic {
     // static定义静态变量,保存班级名称
    static String className = "JAVA开发一班";
    public static void main(String[] args) {
        // 访问静态变量,输出班级名称
        System.out.println(TestStatic.className);
        System.out.println(className);
    }
}

特点:

  1.静态成员变量是属于整个类的全局变量,它不单属于某一个对象;普通成员变量是属于类中的对象,它不能被所有对象共享。

  2.静态成员变量必须在全局进行定义而由于普通成员变量在创建一个对象的时候可以对它进行初始化,因此就不需要单独对它进行定义,只要声明即可。

  3.静态成员变量在没有对象之前就存在。

 

  1.static应用范围:可用于内部类、方法和变量。

  2.标记一个方法为static,意味着这个方法,被所在类的所有实例公用,在类装载时被首先执行,执行一次即被所有该类的实例共享,同时意味着:

    Astatic方法内部不能引用非static变量。

    Bstatic方法不能被子类重写为非static方法。

    C、父类的非static方法不能被子类重写为static方法。

    Dstatic代码块可以用static {}来完成,在类被第一次装载时执行初始化,先于静态方法和其他方法的执行。

  3.标记一个变量为static,则该变量在内存中有不变的位置,相当于全局变量,所有类的实例都访问同一个存储变量区域。对其修改对于所有类的实例来说都是可见和一致的。

(3)静态方法

  与静态变量一样,我们也可以使用static修饰方法,称为静态方法或类方法其实之前我们一直写的 main 方法就是静态方法。

public class TestStaticMethod {
    //使用static关键字声明静态方法
    public static void print(){
        System.out.println("aaaaa");
    }
    public static void main(String[] args) {
        //直接调用静态变量的类名.方法名,推荐方式
        TestStaticMethod.print();
        //也可以通过对象创建,来调用方法
        TestStaticMethod t=new TestStaticMethod();
        t.print();
    }
}

  1.静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员

  如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量。

  2.在普通成员方法中,则可以直接访问同类的非静态变量和静态变量

  3.静态方法中不能直接调用非静态方法,需要通过对象来访问非静态方法

public class TestStaticMethod {
    // static定义静态变量,保存班级名称
    static String className = "JAVA开发一班";
    String className2 = "JAVA开发二班";
    
    //使用static关键字声明静态方法
    public static void print(){
        System.out.println("静态方法中可以直接调用静态变量(同类下):"+className);
        System.out.println("静态方法中可以直接调用静态变量:"+TestStaticMethod.className);
        
        //System.out.println("静态方法中不可以直接调用非静态变量:"+className2);
        //也可以通过对象创建,来调用方法
        TestStaticMethod t=new TestStaticMethod();
        System.out.println("静态方法中,可以先创建对象,再调用非静态变量:"+t.className2);
    }
    //非static关键字声明的方法,普通方法
    public void show(){
        System.out.println("普通方法中可以直接调用静态变量(同类下):"+className);
        System.out.println("普通方法中可以直接调用静态变量:"+TestStaticMethod.className);
        
        System.out.println("普通方法中可以直接调用非静态变量:"+className2);
        //也可以通过对象创建,来调用方法
        TestStaticMethod t=new TestStaticMethod();
        System.out.println("普通方法中,可以先创建对象,再调用非静态变量:"+t.className2);
    }
    public static void main(String[] args) {
        //直接调用静态变量的类名.方法名,推荐方式
        TestStaticMethod.print();
        //同类下,静态方法中可以直接调用静态方法
        print();
        //也可以通过对象创建,来调用方法
        TestStaticMethod t=new TestStaticMethod();
        t.print();
        //但是普通方法,只能通过先创建对象来调用
        t.show();
    }
}

(4)静态初始化块

  在类的声明,可以包含多个初始化块,当创建类的实例时,就会一次执行这些代码块,如果使用static 修饰初始化块,就称为静态初始化块。

  注意:静态初始化块只在类加载时执行,且只会执行一次,同时静态初始化块只能给静态变量赋值,不能给初始化普通的成员变量

  程序运行时静态初始化块最先被执行,然后执行普通初始化块,最后才执行构造方法。

public class TestStatics {
    String name; // 声明变量name
    String sex; // 声明变量sex
    static int age;// 声明静态变量age
    // 构造方法
    public TestStatics() { 
        System.out.println("通过构造方法初始化name");
        name = "tom";
    }
    // 初始化块
    { 
        System.out.println("通过初始化块初始化sex");
        sex = "男";
    }
    // 静态初始化块
    static  { 
        System.out.println("通过静态初始化块初始化age");
        age = 20;
    }
    public void show() {
        System.out.println("姓名:" + name + ",性别:" + sex + ",年龄:" + age);
    }
    public static void main(String[] args) {
        // 创建对象
        TestStatics hello = new TestStatics();
        // 调用对象的show方法
        hello.show();
        /**
         * 通过静态初始化块初始化age
         * 通过初始化块初始化sex
         *    通过构造方法初始化name
         *    姓名:tom,性别:男,年龄:20
         */
    }
}

 

posted @ 2018-05-05 16:15  小码农成长记  阅读(172)  评论(0)    收藏  举报