美文网首页程序员java架构经验分享
做java开发两年了!面试连个static关键词都讲不明白,还想

做java开发两年了!面试连个static关键词都讲不明白,还想

作者: 程序员匡胤 | 来源:发表于2020-09-04 22:18 被阅读0次

    一旦用了static修饰,那么这样的内容不再属于对象自己,而是属于类的,所有本类的对象,都共享一份。不需要创建对象也可使用类名直接调用。静态的内容随着class文件的加载而加载。

    修饰变量

    • 被static修饰的变量叫做静态变量,也叫做类变量。

    • 这个变量属于类本身,而不是属于对象。

    • 没有被static修饰的成员变量叫做实例变量,说明这个变量是属于具体对象的。

    • 当通过类或者某个对象来修改静态变量时,所有使用到这个变量的地方,值都会变化。

    public class Person {
      
      private String name;
      public static int age = 20;
      
      public Person(String name) {
          this.name = name;
      }
    
      public String getName() {
          return name;
      }
    
      public void setName(String name) {
          this.name = name;
      }
    
      public static int getAge() {
          return age;
      }
    
      public static void setAge(int age) {
          Person.age = age;
      }
    
      @Override
      public String toString() {
          return "Person{" +
                  "name='" + name + '\'' +
                  "age='" + age + '\'' +
                  '}';
      }
    }
    
    

    public class Test {
        public static void main(String[] args) {
            Person one = new Person("张三");
            Person two = new Person("李四");
            System.out.println("--------使用类名调用和修改静态变量--------");
            System.out.println("------修改前对象的toString------");
            System.out.println(one.toString());
            System.out.println(two.toString());
            //权限为public时,static修饰的成员变量属于类,可以用类名调用!
            System.out.println("---修改前使用类名调用:"+Person.age);
            //可以直接使用类名调用并修改
            Person.age = 21;
            //权限为private时需要使用get和set方法来调用和修改
            System.out.println("---修改后使用类名调用:"+Person.getAge());
            System.out.println("------修改后对象的toString------");
            System.out.println(one.toString());
            System.out.println(two.toString());
    
            System.out.println("------------------分割线------------------");
    
            System.out.println("--------使用对象名调用和修改静态变量--------");
            //静态变量属于类,使用对象名调用修改后,所有对象和类本身使用该变量时都会变成修改后的值
            System.out.println("例如使用第一个对象修改静态变量值为19");
            one.age = 18;
            System.out.println(one.toString());
            System.out.println(two.toString());
        }
    }
    /*
    输出结果:
    --------使用类名调用和修改静态变量--------
    ------修改前对象的toString------
    Person{name='张三'age='20'}
    Person{name='李四'age='20'}
    ---修改前使用类名调用:20
    ---修改后使用类名调用:21
    ------修改后对象的toString------
    Person{name='张三'age='21'}
    Person{name='李四'age='21'}
    ------------------分割线------------------
    --------使用对象名调用和修改静态变量--------
    例如使用第一个对象修改静态变量值为19
    Person{name='张三'age='18'}
    Person{name='李四'age='18'}
    */
    
    

    修饰方法

    • static修饰的方法叫做静态方法,静态方法属于类。(这种写法在编译之后也会被javac(java语言编程编译器)翻译成“类名.静态方法”)。

    • 可以通过对象名直接调用(如:对象名.静态方法名()),也可以直接通过类名称调用(如:类名称.静态方法名())(推荐使用类名调用,最终也会编译成“类名称.静态方法名()”)。

    • 对于本类当中的静态方法可以省去类名,直接写方法名调用,在编译的时候会编译为“静态方法名()”,所以完全等效。

    • 静态可以直接访问静态,不可以直接访问非静态(在内存中先有的静态,后有的非静态)(先人不知道后人,后人知道先人)。

    • 静态方法中不能使用this关键字,this指的是当前对象,静态方法使用不需要创建对象。

    • 静态方法在java web阶段写service程序时经常使用。

    //本类中使用类名调用和直接调用本质都一样
    public class Test{
        public static void StaticMethod(){
            System.out.println("静态方法执行了!!!");
        }
        public static void main(String[] args) {
            //通过类名调用
            Test.StaticMethod();
            //本类中直接调用
            StaticMethod();
        }
    }
    /*
    静态方法执行了!!!
    静态方法执行了!!!
    */
    //.class文件
    public class Test {
        public Test() {
        }
        public static void StaticMethod() {
            System.out.println("静态方法执行了!!!");
        }
        public static void main(String[] args) {
            StaticMethod();
            StaticMethod();
        }
    }
    
    

    //使用对象名调用和使用类名调用都会编译成"类名.静态方法名()"
    class Test1{
        public static void main(String[] args) {
            Test.StaticMethod();
            Test t = new Test();
            t.StaticMethod();
        }
    }
    //.class文件
    class Test1 {
        Test1() {
        }
        public static void main(String[] args) {
            Test.StaticMethod();
            Test t = new Test();
            Test.StaticMethod();
        }
    }
    
    

    修饰类

    • 在Java中,static一般用来修饰成员变量和成员函数,很少用来修饰类,但是普通类是不可以用static修饰的,只有内部类才可以。

    • static修饰内部类的意义在于,不用创建外部类实例,也可创建内部类。

    public class Test{
        
        public static class Iml{
            public void TestMethod(){
                System.out.println("静态内部类中的方法");
            }
        }
    
        public static void main(String[] args) {
            Iml iml = new Test.Iml();//不用创建外部类实例,也可创建内部类
            iml.TestMethod();
        }
    }
    /*
    静态内部类中的方法
    */
    
    

    静态代码块

    • 特点:当第一次使用本类时,静态代码快执行唯一一次。

    • 执行时,静态代码块比构造方法先执行。

    • 静态代码块典型用途:

    • 用来一次性地对静态成员变量进行赋值。

    public class Person {
        public Person() {
            System.out.println("构造方法执行了!!!");
        }
        static {
            System.out.println("静态方法执行了!!!");
        }
    }
    
    

    public class Test {
        public static void main(String[] args) {
            Person one = new Person();
            Person two = new Person();
        }
    }
    /*执行结果:
        静态方法执行了!!!
        构造方法执行了!!!
        构造方法执行了!!!
    */
    
    

    总结

    • 生命周期

      静态方法和静态变量一样,都属于类本身,在类装在的时候被装载到内存,不会自动销毁,会一直存在于内存中,直到JVM关闭。(但是同时也会导致占用大量资源,使用太多可能导致内存溢出)

      非静态方法和变量属于实例化对象,实例化后才会分配内存,必须通过类的实例化引用,当实例对象被JVM回收之后,也跟着消失。

    • 效率

      静态方法比非静态方法使用效率高。

    • 在内存中的位置

      成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据。

      静态变量数据存储在方法区(共享数据区)的静态区。

    最后

    感谢你看到这里,文章有什么不足还请指正,觉得文章对你有帮助的话记得给我点个赞,每天都会分享java相关技术文章或行业资讯,欢迎大家关注和转发文章!

    相关文章

      网友评论

        本文标题:做java开发两年了!面试连个static关键词都讲不明白,还想

        本文链接:https://www.haomeiwen.com/subject/zoitektx.html