• static,静态关键字的详解


    一,使用static声明属性

    class Person{    // 定义Person类
        String name ;        // 定义name属性,暂时不封装
        int age ;            // 定义age属性,暂时不封装
        String country = "A城" ;    // 定义城市属性,有默认值
        public Person(String name,int age){
            this.name = name ;
            this.age = age; 
        }
        public void info(){    // 得到信息
            System.out.println("姓名:" + this.name + ",年龄:" + this.age + ",城市:" + country) ;
        }
    };
    public class StaticDemo01{
        public static void main(String args[]){
            Person p1 = new Person("张三",30) ;     // 实例化对象
            Person p2 = new Person("李四",31) ;     // 实例化对象
            Person p3 = new Person("王五",32) ;     // 实例化对象
    
            p1.info() ;
            p2.info() ;
            p3.info() ;
        }
    };

    以上代码确实实现了功能,但是如果此时城市名称不叫A城,改叫B城,如果已经产生了5000个对象,那么意味着要修改5000遍对象中

    contry属性。

    所以最好使用static关键字声明属性。

    范例,使用static修改。

    class Person{    // 定义Person类
        String name ;        // 定义name属性,暂时不封装
        int age ;            // 定义age属性,暂时不封装
        static String country = "A城" ;    // 定义城市属性,有默认值,static
        public Person(String name,int age){
            this.name = name ;
            this.age = age; 
        }
        public void info(){    // 得到信息
            System.out.println("姓名:" + this.name + ",年龄:" + this.age + ",城市:" + country) ;
        }
    };
    public class StaticDemo02{
        public static void main(String args[]){
            Person p1 = new Person("张三",30) ;     // 实例化对象
            Person p2 = new Person("李四",31) ;     // 实例化对象
            Person p3 = new Person("王五",32) ;     // 实例化对象
            System.out.println("--------------- 修改之前 -------------") ;
            p1.info() ;
            p2.info() ;
            p3.info() ;
            p1.country = "B城" ;        // 修改static属性
            System.out.println("--------------- 修改之后 -------------") ;
            p1.info() ;
            p2.info() ;
            p3.info() ;
        }
    };

    修改一个对象中的属性,则其他对象的属性全部改变,则证明此属性是所有对象共享的!

    分析:这是内存分配图:

    每一个对象拥有各种的堆空间,堆内存空间中,保存着各自的属性,

    但是static属性是保存在全局数据区之中,所有的对象共同指向全局数据的一个内容。所以一个数据修改后,所有对象内容都会改变。

    JAVA中到底有多少内存区域呢?

    1)栈内存:可以保存对象的名称(保存,访问的堆内存地址)。

    2)堆内存:保存每个对象的全局属性。

    3)全局数据区:保存static类型的属性。

    4)全局代码区:保存所有方法的定义。

    但是也发现一些问题:一般调用static属性,最好使用类名称调用。

    采用”类名称.属性“的形式调用。如上应该用Person.contry="B城";

    既然可以用static声明属性,那么static也可以声明方法。

    二,声明static方法。

    如果一个方法使用了static关键字声明,那么此方法可以使用类名称调用。

    下面将之前代码全部属性进行封装。

    class Person{    // 定义Person类
        private String name ;        // 定义name属性,暂时不封装
        private int age ;            // 定义age属性,暂时不封装
        private static String country = "A城" ;    // 定义城市属性,有默认值,static
        public static void setCountry(String c){ // 此方法可以直接由类名称调用
            country = c ;
        }
        public static String getCountry(){
            return country ;
        }
        public Person(String name,int age){
            this.name = name ;
            this.age = age; 
        }
        public void info(){    // 得到信息
            System.out.println("姓名:" + this.name + ",年龄:" + this.age + ",城市:" + country) ;
        }
    };
    public class StaticDemo04{
        public static void main(String args[]){
            Person p1 = new Person("张三",30) ;     // 实例化对象
            Person p2 = new Person("李四",31) ;     // 实例化对象
            Person p3 = new Person("王五",32) ;     // 实例化对象
            System.out.println("--------------- 修改之前 -------------") ;
            p1.info() ;
            p2.info() ;
            p3.info() ;
            Person.setCountry("B城") ;        // 调用静态方法修改static属性的内容
            System.out.println("--------------- 修改之后 -------------") ;
            p1.info() ;
            p2.info() ;
            p3.info() ;
        }
    };

    注意点:

    使用static方法,不能调用非static属性或方法。(因为static属性和方法所修改的属性都是保存在共享数据区,而非static属性或方法是各自的堆内存数据区)

    三,static的应用

    1)从前面得知,static属性是所有对象共享的,那么就可以使用static属性统计一个类到底产生了多少对象。

    因为每一个对象实例化都要调用构造方法,如果要进行统计,则直接在构造方法中增加一个static属性即可。

    class Demo{    // 定义Person类
        private static int count = 0 ;    // 所有对象共享此属性
        public Demo(){
            count++ ;                     // 只要有对象产生就应该自增
            System.out.println("产生了" + count + "个对象!") ;
        } 
    };
    public class StaticDemo06{
        public static void main(String args[]){
            new Demo() ;            // 增加新对象
            new Demo() ;            // 增加新对象
            new Demo() ;            // 增加新对象
        }
    };

    2)可以使用static为对象进行自动的编名操作,此操作与上面方法非常类似。

    class Demo{    // 定义Person类
        private String name ;            // 保存名字
        private static int count = 0 ;    // 所有对象共享此属性
        public Demo(){
            count++ ;                    // 有对象产生就自增
            this.name = "DEMO-" + count ;    // 自动进行编名操作
        } 
        public Demo(String name){
            this.name = name;            // 可以通过构造赋值
        }
        public String getName(){        // 取得姓名
            return this.name ;
        }
    };
    public class StaticDemo07{
        public static void main(String args[]){
            System.out.println(new Demo().getName()) ;//使用了匿名对象。
            System.out.println(new Demo("LXH").getName()) ;
            System.out.println(new Demo().getName()) ;
            System.out.println(new Demo("MLDN").getName()) ;
            System.out.println(new Demo().getName()) ;
        }
    };
    运行结果:
    DEMO-1
    LXH
    DEMO-2
    MLDN
    DEMO-3
          

    此点在以后java中也会经常实现。

    总结:

    1)声明static属性与非static属性的区别。

    2)使用类名可以直接调用static属性。

    3)使用static方法,不能调用非static属性或方法。

  • 相关阅读:
    PHP调试的时候出现了警告:
    快报滚动
    js foreach、map函数
    箭头函数和普通函数的区别
    flex布局
    react+propTypes
    手机尺寸
    less的使用
    发现是在IE6-IE9下,下列元素table,thead,tfoot,tbody,tr,col,colgroup,html,title,style,frameset的innerHTML属性是只读的
    div+css 组织结构
  • 原文地址:https://www.cnblogs.com/alsf/p/5517014.html
Copyright © 2020-2023  润新知