zoukankan      html  css  js  c++  java
  • java static和final关键字

    static 用法

    1.static 变量

    static变量又称为静态变量,静态变量保存在方法区静态域中,一个类的静态变量被其所有实例共享。

    2.static方法

    静态方法不与包含它的任何对象关联,即使没有创建对象,也可使用,例:

    package cn.wangze.test;
    
    class Demo{
        public static int i = 19;
    }
    
    public class staticDemo {
        private static Demo demo1 = new Demo();
        private static Demo demo2 = new Demo();
        public static void main(String[] args){
            System.out.println(Demo.i);     //19
            System.out.println(demo1.i);    //19
            System.out.println(demo2.i);    //19
            demo1.i++;
            System.out.println(Demo.i);        //20
            System.out.println(demo1.i);    //20
            System.out.println(demo2.i);    //20
            Demo.i++;
            System.out.println(Demo.i);        //21
            System.out.println(demo1.i);    //21
            System.out.println(demo2.i);    //21
        }
    }

    3.static代码块

    static代码块在类初次被引用或者实例化时执行且只执行一次,一个类里可以有多个static代码块,会按照顺序执行,例:

    public class StaticTest {
    
        static {
            System.err.println("Wave hands");
        }
    
        public static void sayHello(){
            System.err.println("say Hello");
        }
    
    }
    
    class Greeting{
    
        public static void main(String[] args) {
            StaticTest.sayHello();
        }
    }

    4.static类

    普通类是不能被static修饰的,static只能修饰内部类;这种内部类通常称为 嵌套类

    “如果不需要内部类对象与其外围类对象之间有联系,那么可以将内部类声明为static”(《java编程思想p201》);

    普通的内部类对象都会隐式的保存一个引用指向创建他的外部类,然而关于嵌套类:

    1)要创建嵌套类的对象,并不需要其外围类的对象。

    2)不能从嵌套类的对象中访问非静态的外围类对象。

    例如jdk中ThreadLocal类就有较多的应用;

    /**关于内部类部分后续讨论*/

    扩展内容

    类从加载到虚拟机内存中开始,到卸载内存位置,它的真个声明周期包括:加载、验证、准备、解析、初始化、使用、卸载;

    有且仅有以下四种情况下,类必须进行初始化

    1)遇到new(使用new关键字实例化对象)

    getstatic、putstatic(读取或设置一个类的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外))

    invokestatic(调用一个类的静态方法的时候)

    2)使用java.lang.reflect包的方法对类进行反射调用的时候

    3)初始化一个类时,发现其父类没有进行过初始化的时候

    4)当虚拟机启动时,用户需要指定一个要执行的主类,虚拟机会初始化这个主类;

    对于静态字段,只有直接引用定义这个字段的类才会触发该类的初始化,而通过子类引用父类的字段,只会触发父类的初始化,而不会触发子类的初始化,例:

    package com.neal.tutorial.basic.keyword;
    
    public class StaticTest {
    
        static int a = 5;
    
        static {
            System.err.println("a in parent: " + a);
        }
    
    }
    
    class SubStatic extends StaticTest {
    
        static int b = 10;
    
        static{
            System.err.println(b);
        }
    
    }
    
    class Greeting {
    
        public static void main(String[] args) {
            System.err.println(SubStatic.a);
        }
    }

    可以看出子类中静态代码块并没有执行;

    final关键字用法

    1.变量

    1)基本类型:

    当我们需要一个编译时不改变常量,或者一个运行时被初始化后就不改变的值时,通常定义一个final修饰的基本类型变量

    当与static一起使用时,意为一个只有一份的常量(即多个实例共享)

    2)对象:

    当变量类型为对象时,final变量的引用在初始化后不可更改,但是引用指向的对象值是可变的,例如数组、Map、List等

    3)参数列表

    当在参数列表中声明参数为final时,意味着在方法中只能读取参数引用的对象,而无法修改参数引用指向的对象,这一特性主要用于向匿名内部类传递参数

    2.final方法

    final方法一般用于两种情景下

    1)想要锁定方法,防止任何继承类修改它的含义,确保在继承中使方法行为保持不变,并且不会被覆盖

    2)出于性能考虑,在java早期实现中(现在不鼓励这么做)如果一个方法被指明为final,就是允许编译器将针对该方法的所有调用都转为内嵌调用

    内嵌机制是指final方法会在编译时进行inline优化,即在编译时直接调用方法代码替换,而不是在运行时。而非final方法可能存在被子类重写,由于多态的原因,并不能在编译时就确定调用的是哪个方法

    3.final类

    final类不能够被继承,一般在确定该类不需要子类时,将类定义为final类型

    在jdk源码中,String类就被定义为final类型

  • 相关阅读:
    kubeadm init 时从本地私有仓库下载镜像
    Kubernetes 1.6新特性
    kukubeadm 1.6.1 + docker1.2.6 安装问题
    nginx 配置
    使用nginx替换Ingress
    Docker存储方式选型建议
    iptables相关
    kubenetes master使用curl 操作API
    kubernetes 一些基本的概念
    Codeforces Round #161 (Div. 2) D. Cycle in Graph(无向图中找指定长度的简单环)
  • 原文地址:https://www.cnblogs.com/wuqiance/p/11599008.html
Copyright © 2011-2022 走看看