zoukankan      html  css  js  c++  java
  • 菜鸡的Java笔记 第十七 static 关键字

    static 是java中定义的一个关键字,主要是描述全局的概念,所以利用static关键字可以定义属性,定义方法
            但是在90%的情况下,我们的开发代码很少会去直接编写static
    */

    /*    利用static定义属性
            现在假设定义一个只描述中国人的类,那么在这个类里面肯定要包含有姓名,年龄,国家,
            所以按照之前所学的概念来进行设计,就可以的出如下的结果:

    class Person{
        private String name:
        private int age:
        String country = "中华人民共和国":  // 此属性暂时不封装
        public Person(String name,int age){
            this.name = name:
            this.age = age:
        }
        public String getlnfo(){
            return"姓名"+this.name+"年龄"+this.age+"国籍"+this.country:
        }
    }
    public class staticKeyword{
        public static void main(String args[]){
            Person perA = new Person("小",10):
            Person perB = new Person("中",20):
            Person perC = new Person("大",30):
            System.out.println(perA.getlnfo()):
            System.out.println(perB.getlnfo()):
            System.out.println(perC.getlnfo()):
        }
    }
    /*
    结果:
    姓名;小,年龄;10,国籍;中华人民共和国
    姓名;中,年龄;20,国籍;中华人民共和国
    姓名;大,年龄;30,国籍;中华人民共和国
    */

                
                但是对于以上的程序的内存关系中就会发现问题所在了
                如果说现在玩穿越了,中国退回到了唐朝,中国14亿人口,14亿对象,14亿对象修改一个属性

    class Person{
        private String name:
        private int age:
        String country = "中华人民共和国":  // 此属性暂时不封装
        public Person(String name,int age){
            this.name = name:
            this.age = age:
        }
        public String getlnfo(){
            return"姓名"+this.name+"年龄"+this.age+"国籍"+this.country:
        }
    }
    public class staticKeyword{
        public static void main(String args[]){
            Person perA = new Person("小",10):
            Person perB = new Person("中",20):
            Person perC = new Person("大",30):
            perA.country = "唐朝":
            System.out.println(perA.getlnfo()):
            System.out.println(perB.getlnfo()):
            System.out.println(perC.getlnfo()):
        }
    }
    /*
    结果:
    姓名;小,年龄;10,国籍;唐朝
    姓名;中,年龄;20,国籍;中华人民共和国
    姓名;大,年龄;30,国籍;中华人民共和国
    */

               
                这样的话对于整个代码的维护实在是太可怕,而造成这种问题的根源在于:
                    类中的普通属性是每一个对象都独自拥有的,但是这样的设计明显不符合当前的环境,所以最好的做法是将国家的这个属性设置为公共属性
                    所有的对象都可以共享此属性,如果要想实现这样的操作,就可以通过static 关键字来进行定义
                范例:使用static关键字定义

    class Person{
        private String name:
        private int age:
        static String country = "中华人民共和国":  // 此属性暂时不封装
        public Person(String name,int age){
            this.name = name:
            this.age = age:
        }
        public String getlnfo(){
            return"姓名"+this.name+"年龄"+this.age+"国籍"+this.country:
        }
    }
    public class staticKeyword{
        public static void main(String args[]){
            Person perA = new Person("小",10):
            Person perB = new Person("中",20):
            Person perC = new Person("大",30):
            perA.country = "唐朝": // 修改了一个对象的属性
            System.out.println(perA.getlnfo()):
            System.out.println(perB.getlnfo()):
            System.out.println(perC.getlnfo()):
        }
    }
    /*
    结果:
    姓名;小,年龄;10,国籍;唐朝
    姓名;中,年龄;20,国籍;唐朝
    姓名;大,年龄;30,国籍;唐朝
    */

                   
                    通过执行结果发现,修改了一个对象的属性之后,所有对象的属性都发生了改变
                    所以这样的属性称为公共属性,公共属性必须通过static定义,而对于公共属性的内容保存不会在栈内存也不在堆内存
                    而是会存在于全局数据区中,所有的方法保存在全局代码区之中
                
                    但是现在出现了一个问题,既然static属于全局属性,那么由一个对象进行修改是否合适呢/
                    现在通过一个对象改的:
                        perA.country = "唐朝": // 修改了一个对象的属性
                    
                    很明显这是不合适的,最好的做法是利用所有对象的一个最高的代表来操作,这个代表就是类
                    所以对于static定义的属性可以由类名称直接进行调用,所以这样的属性也被称为类属性
                        Person.country = "唐朝": // 直接通过类调用
                
                    此时的类中存在有static属性以及非static属性,但是在这里面需要注意:
                        所有的非static属性都是在对象实例化的时候才会进行内存的分配
                        所有的static属性可以在没有实例化对象产生的情况下直接使用
                范例:直接调用类属性

    class Person{
        private String name:
        private int age:
        static String country = "中华人民共和国":  // 此属性暂时不封装
        public Person(String name,int age){
            this.name = name:
            this.age = age:
        }
        public String getlnfo(){
            return"姓名"+this.name+"年龄"+this.age+"国籍"+this.country:
        }
    }
    public class staticKeyword{
        public static void main(String args[]){
            System.out.println(Person.country):
        }
    }
    /*
    结果:
    中华人民共和国
    */

               
                修改

    class Person{
        private String name:
        private int age:
        static String country = "中华人民共和国":  // 此属性暂时不封装
        public Person(String name,int age){
            this.name = name:
            this.age = age:
        }
        public String getlnfo(){
            return"姓名"+this.name+"年龄"+this.age+"国籍"+this.country:
        }
    }
    public class staticKeyword{
        public static void main(String args[]){
            System.out.println(Person.country):
            Person.country = "北宋":
            System.out.println(Person.country):
        }
    }
    /*
    结果:
    中华人民共和国
    北宋
    */

    ---

    class Person{
        private String name:
        private int age:
        static String country = "中华人民共和国":  // 此属性暂时不封装
        public Person(String name,int age){
            this.name = name:
            this.age = age:
        }
        public String getlnfo(){
            return"姓名"+this.name+"年龄"+this.age+"国籍"+this.country:
        }
    }
    public class staticKeyword{
        public static void main(String args[]){
            System.out.println(Person.country):
            Person.country = "北宋":
            System.out.println(Person.country):
            System.out.println(new Person("小",10).getlnfo):
        }
    }
    /*
    结果:
    中华人民共和国
    北宋
    姓名;小,年龄;10,国籍;北宋
    */

               
                虽然static的属性定义在类之中,但是其是完全独立的,不受类实例化对象的控制
                在90%的情况下类的设计都会使用非static属性,只有在10%表示公共的属性,或者是与类实例化无关的属性定义时才会考虑使用static
                        
    */

    /*    static 定义方法
            利用static定义的属性可以直接通过类名称进行访问,但是static也可以用于方法的定义上,同样,这个方法可以由类名称直接进行调用
            范例:定义static方法

    class Person{
        private String name:
        private int age:
        private static String country = "中华人民共和国"public Person(String name,int age){
            this.name = name:
            this.age = age:
        }
        public static void setCountry(String c){
            country = c:
        }
        public static String getCountry(){
            return country:
        }
        public String getlnfo(){
            return"姓名"+this.name+"年龄"+this.age+"国籍"+this.country:
        }
    }
    public class staticKeyword{
        public static void main(String args[]){
            // 此时没有实例化对象产生
            System.out.println(Person.getCountry()):
            
        }
    }
        /*结果:
        中华人民共和国 */

         ...          

    class Person{
        private String name:
        private int age:
        private static String country = "中华人民共和国"public Person(String name,int age){
            this.name = name:
            this.age = age:
        }
        public static void setCountry(String c){
            country = c:
        }
        public static String getCountry(){
            return country:
        }
        public String getlnfo(){
            return"姓名"+this.name+"年龄"+this.age+"国籍"+this.country:
        }
    }
    public class staticKeyword{
        public static void main(String args[]){
            // 此时没有实例化对象产生
            System.out.println(Person.getCountry()):
            Person.setCountry("清朝"):
            System.out.println(Person.getCountry()):
            System.out.println(new Person("少爷",21).getlnfo()):
        }
    }
    /*
    结果:
    中华人民共和国
    清朝
    姓名:少爷。年龄:21,国籍:清朝
    */

               
                static的方法依然不受到实例化对象的控制,所以可以由类名称直接调用
                但是此时类中的方法就存在有两种了:static方法,非static方法那么这两种方法之间互相访问就出现问题了
                    所有的非static方法可以直接调用非static方法或static属性

    static 方法只允许调用static方法和static属性
                    非static方法允许调用 static 和非 static 定义
                    static 方法不允许调用非 static 操作以及 this
                        static 定义必须产生实例化对象后才会分配内存空间并且调用,而 static 可以在没有实例化对象的时候进行调用
                        所以在 static 方法之中不存在有this当前对象概念

    class Person{
        private String name:
        private int age:
        private static String country = "中华人民共和国"public Person(String name,int age){
            this.name = name:
            this.age = age:
        }
        public static void setCountry(String c){
            country = c:
        }
        public static String getCountry(){
            return country:
        }
        public String getlnfo(){
            System.out.println(this.getCountry()):
            return"姓名"+this.name+"年龄"+this.age+"国籍"+this.country:
        }
    }
    public class staticKeyword{
        public static void main(String args[]){
            
            System.out.println(new Person("少爷",21).getlnfo()):
        }
    }
    /*结果:
    姓名:少爷。年龄:21,国籍:清朝
    
    */

                   
                    static 方法不能够直接调用非static方法或者是非static属性

    class Person{
        private String name:
        private int age:
        private static String country = "中华人民共和国"public Person(String name,int age){
            this.name = name:
            this.age = age:
        }
        public static void setCountry(String c){// 为什么不是country:因为你在调用static方法时可能还没有实例化对象 所以是 c  也没有加 this
            country = c:
        }
        public static String getCountry(){
            getlnfo():
            return country:
        }
        public String getlnfo(){
            System.out.println(this.getCountry()):
            return"姓名"+this.name+"年龄"+this.age+"国籍"+this.country:
        }
    }
    public class staticKeyword{
        public static void main(String args[]){
            
            System.out.println(new Person("少爷",21).getlnfo()):
        }
    }
    //结果:(出错)


                分析?为什么会存在有这样的定义?
                    所有的static属性或方法可以在类没有实例化对象的时候进行直接使用
                    所有非static属性或方法必须在类产生实例化对象之后才可以进行调用
                
                那么什么时候使用static方法呢?
                    类设计的过程之中90%的方法都使用非static方法定义
                    如果一个类中没有任何的属性,那么这个类不需要定义普通方法,只需要定义static方法
                范例:对比一下两种代码
                    1.

    class Ssd{
        public int add(int x,int y){
            return x + y:
        }
    }
    public class staticKeyword{
        public static void main(String args[]){
                
            System.out.println(new Ssd().add(10,20)):
        }
    }


                    2.

    class Ssd{
        public static int add(int x,int y){
            return x + y:
        }
    }
    public class staticKeyword{
        public static void main(String args[]){
                
            System.out.println(Ssd.add(10,20)):
        }
    }
        
    //结果:30 

                   
                    因为此时Ssd 类没有属性,没有属性就不需要使用到堆内存。
                    而如果现在使用了第一种方式,那么会开辟一块无用的堆内存空间
                    所以这个时候很明显,第二种方式更加合理

    */

    /*    观察主方法
            在最早讲解方法定义的时候实际上给出了两种方案
                第一种:某一个方法定义在主类中,并且由主方法直接调用,定义格式:
                    public static 返回值类型 方法名称(){}
                第二种:某一个方法定义在了类中,并且由实例化对象进行调用,定义格式:
                    public 返回值类型 方法名称(){}
                
            那么现在来做一个简单分析

    public class staticKeyword{
        public static void main(String args[]){
            println():
        }
        public static void println(){
            System.out.println("*****Hello Werld****"):
        }
    }
    /*
    结果  
    *****Hello Werld****
    */


                
                如果没有加 static呢?   那就会出错
                但是反过来,这个时候只能够通过产生本类实例化对象的方式来进行调用

    public class staticKeyword{
        public static void main(String args[]){
            new staticKeyword().println():  // 对象。方法()
        }
        public void println(){ //  非static方法
            System.out.println("*****Hello Werld****"):
        }
    }

                 
                在以后所编写的代码过程之中,主类中不会编写什么方法,大部分的方法都会封装在类之中,通过产生对象调用
            
            java 中的主方法可以说是历史之最长的
                public:是一种访问权限,表示所有的操作者都可以看见
                static:执行一个类的时候输入:“java 类名称”,表示由类直接调用
                void:主方法是一切的起点,开始了就继续把
                main:是一个系统定义好的方法名称
                Stirng args[]:程序执行时的输入参数,初始化参数的
            范例:取得初始化输入参数

    public class staticKeyword{
        public static void main(String args[]){
            for(int x = 0:x<args.length:x++){
                System.out.println(args[x]):
            }
        }
    }


                如果要输入参数,则在解释java 程序时,类后面利用空格设置,每个参数间使用空格区分

    执行程序设置参数:java 类名称 内容         例如:Java TestDemo hello world
                如果参数本身就有空格则要使用““”声明:Java TestDemo ”hello world“

    */

    /*    static应用
            static在一些系统类库上会大量的出现,那么这些就有可能是static方法所导致的
            这次重点来看static属性。static属性有一个最好的特点在于:公共属性,所有对象都可以对其进行修改
            范例:实现一个对象的个数统计
                所有的新的实例化对象产生式都一定要调用构造方法,所以可以在构造方法里面增加一个统计

    class Perdon{
         private static int count = 1: // 统计个数
         public Peron(){
             System.out.println("对象个数:"+count++):
         }
     }
    public class staticKeyword{
        public static void main(String args[]){ //
            new Person():
            new Person():
            new Person():
            new Person():
            new Person():
            new Person():
            }
        }
    }
    /*
    结果:
    对象个数:1
    对象个数:2
    对象个数:3
    对象个数:4
    对象个数:5
    对象个数:6
    */

               
            实际上可以将以上的程序进一步的修改,现在假设Person类中存在有一个name的属性,那么在Person类提供有一个构造方法:
            一个是负责接收 name 属性内容的,一个是无参的但是要求不管使用那种构造方法都应该为name属性设置一个名字,而不是nuill
            范例:为属性自动命名

    class Perdon{
         private static int count = 1: // 统计个数
         private String name:
         public Peron(){
            this("无名氏-"+count++):
         }
         public Person(String name){
             this.name = name:
         }
         public String getName(){
             return this.name:
         }
     }
    public class staticKeyword{
        public static void main(String args[]){ //
            System.out.println(new Person().getName()):
            System.out.println(new Person().getName()):
            System.out.println(new Person("ssd").getName()):
            }
        }
    }
    /*
    结果:
    无名氏-1
    无名氏-2
    ssd 3
    */

               
                这样的操作在以后的高级部分会见到其应用

            在类的首要设计过程中不要去考虑static属性或者方法
            使用static方法大部分情况下有两种可能性
                可以不受到类实例化的对象控制
                类中就没有提供有普通属性

    */

  • 相关阅读:
    hdu 1023 卡特兰数+高精度
    hdu 1568 Fibonacci 快速幂
    hdu 3054 Fibonacci 找循环节的公式题
    hdu 5167 Fibonacci 打表
    hdu 4165 Pills dp
    HDU 5791 Two DP
    BZOJ 2152: 聪聪可可 树分治
    HDU 5213 Lucky 莫队+容斥
    HDU 5145 NPY and girls 莫队+逆元
    BZOJ 3289: Mato的文件管理 莫队+BIT
  • 原文地址:https://www.cnblogs.com/mysterious-killer/p/10059902.html
Copyright © 2011-2022 走看看