zoukankan      html  css  js  c++  java
  • static 和 final 和 static final

    众所周知,static 是静态修饰关键字:可以修饰变量,程序块,方法,类。

    1.修饰变量。

    得知:如果static修饰的是变量,则JVM会将将其分配在内存堆上,该变量就与对象无关,所有对该变量的引用都指向同一个地址。

    因此我们使用该变量的时候,直接指明类的静态变量,当然修饰符必须 public

    1 public class StaticBean {
    2     public static String A = "A";
    3 }

    使用方式

    1 public static void main(String[] args) throws Exception{
    2         System.out.println(StaticBean.A);
    3     }

    2.修饰程序块,猜猜输出结果是什么?。

     1 public class BaseTest {
     2     
     3     static{
     4         System.out.println("B");
     5     }
     6 
     7     public static void main(String[] args) throws Exception{
     8         System.out.println("A");
     9     }
    10 }

    结论:JVM就会优先加载静态块中代码,因此会优先输出B,static 修饰代码块,这主要用于系统初始化。

    B
    A

    3.修饰方法:在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象,静态方法在访问本类的成员时,只允许访问静态成员,而不允许访问实例成员变量和实例方法。

    
    
    public class StaticBean {
    public static String A = "A";
    public String D;
    public static void getMessage(){
    System.out.println(A);
    System.out.println(D);
    }
    }

    上面代码,哪句是错误的,很显然。

    System.out.println(D);

    4.修饰类。在我们的熟知之中,static 修饰符一般用于修饰变量,程序块,方法,但是什么时候使用static来修饰类呢?

    内部类。如果在外部类声明为static,程序会编译都不会过。

    内部类特点如下:

    1.不持有外部类的引用(普通内部类持有)
    2.可以直接创建实例,不需要先创建外部类(普通内部类需要)
    3.可以有静态成员变量、方法(普通内部类不行)和非静态成员变量、方法
    4.只可以直接访问外部类静态成员,不可以直接访问外部类的非静态成员(普通内部类可以),需要通过传入外部类引用的方式才能访问
    5.加载一个类时,其内部类不会同时被加载。一个类被加载,当且仅当其某个静态成员(静态域、构造器、静态方法等)被调用时发生
     

    那就很简单引出,什么时候会使用静态内部类呢? 我们来看下以下一个例子

     1 public class Outer {
     2     private int i = 0;
     3 
     4     public Outer() {
     5         i++;
     6         System.out.println("=====init Outer "+i+"====");
     7 
     8     }
     9 
    10     public static Outer getInstance(){
    11         return Inner.INSTANCE;
    12     }
    13     //静态内部类
    14     public static class Inner{
    15         private static final Outer INSTANCE = new Outer();
    16     }
    17 }

    调用方

    1 public class BaseTest {
    2     public static void main(String[] args) throws Exception{
    3         for(int i = 0; i < 1000;i++) {
    4             Outer.getInstance();
    5         }
    6     }
    7 }

    输出结果:

    =====init Outer 1====

    我们总结下:

    由于 INSTANCE 是常量,因此只能赋值一次;它还是静态的,因此随着内部类一起加载,这种也是单例懒汉模式的一种实现方式,同时保证了线程安全。

    final 关键字可以用来修饰类,方法和变量

    1.修饰类

    表示该类不允许被继承,final类中的成员方法都会被隐式的指定为final方法。

    public final class FinalBean {
    
        public  void test(){
    
        }
    }

    2.修饰方法

    表示该方法不能被重写,一个类的private方法会隐式的被指定为final方法。

    以下例子SunFinalBean的test方法报错。

    public class FinalBean {
    
        public final void test(){
    
        }
    
        public class SunFinalBean extends FinalBean{
            public void test(){
                
            }
        }
    }

    3.修饰变量

    表示该变量必须初始化,且值不能改变。如果是基本类型则值不能改变,如果是引用类型,则引用地址不能改变,但是这个引用所指向的对象里面的内容还是可以改变的。

     猜猜看,以下那句通不过编译器编译。

    public class FinalBean {
        private final int i = 0;
        private final int j;
        private final String name = "";
    
        public FinalBean(){
            j = 1;
            this.name.concat("123");
            this.name = "123";
        }
    }

    这句,记住final的原理即可理解,那为什么this.name.concat("123");不会报错呢,因为底层实现是返回一个新的String对象

    this.name = "123";

    那static final 一起用:

    static修饰的属性强调它们只有一个,final修饰的属性表明是一个常数(创建后不能被修改)。static final修饰的属性表示一旦给值,就不可修改,并且可以通过类名访问。

    static final也可以修饰方法,表示该方法不能重写,可以在不new对象的情况下调用。

  • 相关阅读:
    m.baidu.com/?tn=simple 开始有广告了。。。
    一些话
    sublime text3中如何使用PHP编译系统
    遇到了一个特别有意思的题
    RVS PA-1800 功放参数
    TP框架修改后台路径方法
    换手机号之前需要看看
    layui跨域问题的解决
    Send me
    单细胞文章分享:Molecular Diversity of Midbrain Development in Mouse, Human, and Stem Cells
  • 原文地址:https://www.cnblogs.com/HA-Tinker/p/10674226.html
Copyright © 2011-2022 走看看