zoukankan      html  css  js  c++  java
  • java关键字static用法详解

    java中有53个关键字,其中包含2个保留字,这篇文章主要介绍一下static这个关键字。

    static在java中算是一个比较常见的关键字,有着多种用法,因此很有必要好好地了解一番。

    一、定义

    static:表明具有静态属性(源自百度百科的解释)。

    二、用法

    static主要有以下用法:修饰成员变量,修饰成员方法,静态代码块,静态内部类,静态导包。

    1.修饰成员变量:被static修饰的成员变量,我们将之称为静态变量或类变量,相比于普通的成员变量,它有着以下几点不同之处:能够被所有的对象所共享;随着类的加载而存在;它存在于方法区的静态区,JVM只为它分配一次内存空间;有两种调用方法,通过类名来调用或通过对象来调用。

    public class Person {
        //成员变量
        private String name;
        //静态变量(类变量)
        private static int age;
        
        public static void main(String[] args){
            //静态变量可直接通过类名调用,随着类的加载而存在,类的消失而消失
            Person.age = 10; 
            
            Person person = new Person();
            /*成员变量只能通过对象来调用,并且随着对象的创建而存在,
             *随着对象的回收而销毁。
             */
            person.name = "小明";
            //静态变量也可以通过对象来调用
            person.age = 12;
        }
    }

    接下来看一下静态变量和成员变量在内存中的位置:

    当我们new一个对象,并给其中的成员变量赋值以后,JVM会在堆中开辟出一个空间,用以存放这个对象,每当我们new一个对象时,JVM都会在堆中开辟出一个空间,若该变量是静态变量,则其存在于方法区的静态区中,如下图所示:

    通过图可以看出来,当变量age用了static修饰称为静态变量后,对象person将不再拥有age这一个属性,age这一属性将由person类掌管,即无论你new出多少个person对象,age属性只有一个,如果某一个对象对age属性进行了修改,那么所有的对象中的age属性值将会发生改变,这将会是一件很糟糕的事,所以一般很少会这样定义静态变量。

    2.修饰成员方法:被static修饰的成员方法,我们称之为静态方法,相比于普通的成员方法,它有着如下几点不同之处:静态方法可以通过类直接调用;静态方法只能访问静态变量;静态方法中不可以使用this或者super关键字;主函数是静态的。

    public class Person {
        //成员变量
        private String name;
        //静态变量(类变量)
        private static int age;
        
        public void show(){
            //非静态方法可以直接访问类的静态变量,成员变量,静态方法
            age = 10;
            name = "小花";
            view();
            System.out.println("这是一个普通成员方法");
        }
        
        public static void view(){
            age = 12;
            //静态方法不可以直接访问类的非静态成员和方法
            Person person = new Person();
            person.name = "小明";
            person.show();
            System.out.println("这是一个静态方法");
        }
        
        public static void main(String[] args) {
            //静态方法可以通过类名直接调用
            Person.view();
            
            Person person = new Person();
            //静态方法也可以通过对象调用
            person.view();
            //非静态方法只能通过对象调用
            person.show();
        }
    }

    3.静态代码块:随着类的调用或创建实例而执行,并且只执行一;优于主函数的执行;用于初始化类。

    class Person { 
        { 
            System.out.println("父类代码块"); 
        } 
        static { 
            System.out.println("父类静态代码块"); 
        } 
        public Person(){ 
            System.out.println("父类构造方法"); 
        } 
    } 
    
    class Student extends Person { 
        { 
            System.out.println("子类代码块"); 
        } 
        static { 
            System.out.println("子类静态代码块"); 
        } 
        public Student(){ 
            System.out.println("子类构造方法"); 
        } 
    } 
    
    class Test { 
        public static void main(String[] args) { 
            new Student();
        } 
    }

    当执行上述代码的时候,可以看到结果:

    父类静态代码块
    子类静态代码块
    父类代码块
    父类构造方法
    子类代码块
    子类构造方法

    当我们去执行new Student()方法的时候,程序会首先去找它的父类,看看父类里面有没有静态代码块,如果有,则选择执行静态代码块里的内容,接下来才会回到子类,看看它里面有没有静态代码块,如果有,那就执行,接着会再度回到父类,查找父类的代码块,执行完以后会接着执行父类的构造方法,最后才会执行子类的代码块,构造方法。子类的构造方法,不管是有参构造还是无参构造,它都会先去寻找父类的无参构造方法,如果父类没有无参构造方法,那么子类必须使用super来调用父类的有参构造方法,否则编译不通过。

    注意:静态代码块对于定义在它后面的静态变量,可以赋值,但是不允许访问。

    4.静态内部类:在定义内部类的时候,在前面加上一个static,则这个内部类就成为了静态内部类,静态内部类和普通内部类相比,有着一些不同之处,因此所起的作用也是有很大的不同,不同之处主要有以下几点:非静态内部类中,不能声明静态成员或静态方法,只有静态内部类中才可以声明或定义静态成员或静态方法;非静态内部类中,可以任意访问外部类的成员方法或者成员属性,但是静态内部类却只能访问外部类中的静态成员或静态方法,不可以访问非静态成员或非静态方法;在一个外部类中创建非静态内部类时,内部类的实例一定要绑定在外部类中,即需要在外部类中new一个内部类的对象,但如果在一个外部类中创建一个静态内部类,则不需要此操作,即静态内部类的实例不需要绑定在外部类中。

    public class Person {
        public static class Demo{ 
            Demo(){
                System.out.println("这是一个静态内部类");
            }
        }
        
        public class Demo1{ 
            Demo1(){
                System.out.println("这是一个内部类");
            }
        }
    }
    
    
    class Test {   
        public static void main(String[] args) {
    Person person = new Person(); //实例化Person person.new Demo1(); //调用内部类 new Person.Demo(); //调用静态内部类 } }

    5.静态导包:静态导包就是java包的静态导入,用import static代替import静态导入包是JDK1.5中的新特性。

    没用静态导包之前的书写方式:

    class Test {
        public static void main(String[] args) {
            System.out.println(Integer.MAX_VALUE);
            System.out.println(Integer.toHexString(42));
        }
    }

     用静态导包的书写方式:

    import static java.lang.System.out;
    import static java.lang.Integer.*;
    
    class Test {
        public static void main(String[] args) {
            out.println(MAX_VALUE);
            out.println(toHexString(42));
        }
    }

    在使用静态导包之后,在不与当前类的方法名冲突的情况下,无需使用“类名.方法名”的方法去调用类方法了,直接可以采用"方法名"去调用类方法,就好像是该类自己的方法一样使用即可。

    总结:作为一名刚入行的java小菜鸟,需要不断地学习方可进步,所以在文章中可能有些错误或者不当之处,欢迎大家积极指出,共同进步。

    参考:

    https://www.cnblogs.com/dotgua/p/6354151.html

  • 相关阅读:
    Javascript模块化编程(三):require.js的用法
    【excle基础】如何去掉excel某一列中的字段的空格
    【阅读笔记】数据库管理员的第一本书阅读笔记
    【MYSQL命令】查看一个表的建表语句
    【MYSQL经验】MYSQL经验总结
    【数据库设计】数据库设计规范
    【MongoDB安装】MongoDB在centos linux平台安装
    【MYSQL命令】查看日志是否开启及日志过期天数
    【转】什么是原子性,什么是原子性操作?
    【redis的搭建】centos6.4下搭建redis
  • 原文地址:https://www.cnblogs.com/libinhyq/p/9359949.html
Copyright © 2011-2022 走看看