Java基础之final、static关键字

一、前言

  关于这两个关键字,应该是在开发工作中比较常见的,使用频率上来说也比较高。接口中、常量、静态方法等等。但是,使用频繁却不代表一定是能够清晰明白的了解,能说出个子丑演卯来。下面,对这两个关键字的常见用法做点总结记录,方便之后的回顾以及突击知识点。

二、关键字 final

  final,一如字面意思 “最终的”,大体在 Java 中表示 “不可变的”。可用来修饰类、方法、方法参数以及变量。

  1、修饰类

   final 在修饰类的时候,代表的是此类不能被继承。也就是说如果一个类确定不会被继承使用,则可以设计成 final类型的。典型的例子就是 String 类。

  2、修饰方法

  final 修饰的方法,能被继承,但是不能重写。可以重载。

  3、修饰方法参数

  final 在修饰方法参数的时候,表示的是在执行方法的内部,不能够去改变参数的值。但是如果是引用对象,是可以改变应用对象的属性值。

  4、修饰变量

  final 在修饰变量,代表的是不可变,也即是常说的 “常量”。 final 在修饰的时候,允许一次赋值,之后在生命周期类,不允许对其进行修改。

  修饰变量存在两种情况:基本类型的数据 和  对象数据。在修饰基本类型数据的时候,值是不可变的。在修饰对象数据的是,对象的引用是不可改变的,但是,可以修改对象内部的属性值。

  final 修饰的变量必须在使用前进行初始化,一种方式是在声明的时候就给出默认值。还有一种就是通过构造方法去设置。

  5、代码示例

package com.cfang;

import java.util.Calendar;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class T3 {

    public static void main(String[] args) {
        // -- 修饰变量
        final int b = 0;
        /**
         *     编译报错:The final local variable b cannot be assigned. It must be blank and not using a compound assignment
         */
//        b = 2;

        // -- 修饰方法参数
        DemoCls cls = new DemoCls();
        cls.setAge(10);
        log.info("democls age : {}", cls.getAge());
        int a = 10;
        sayHello(a, cls);
        log.info("after call sayHello, democls age : {}", cls.getAge());
    }

    private static void sayHello(final int a, final DemoCls cls) {
        /**
         *     编译报错:The final local variable a cannot be assigned. It must be blank and not using a compound assignment
         */
//        a = 11;
//        cls = new DemoCls();

        cls.setAge(11);
    }
}

@Data
class DemoCls{
    private int age;
}

// -- 修饰方法
@Slf4j
class Person {
    public final void saySth() {
        log.info("i am person");
    }
}

@Slf4j
class Male extends Person{
    /**
     *     编译出错 : Cannot override the final method from Person
     *     修饰的方法不能够被重写
     */
//    public final void saySth() {
//        log.info("i am male");
//    }

    public final void saySth(String msg) {
        log.info("i am male");
    }
}

  其中,修饰方法参数,如果是引用对象,是可以改变对象的属性值,这一点也很好理解:cls 是引用变量,final 修饰引用变量,只是限定了此引用变量 cls 的引用不能改变,而实际引用的对象的本身的值是可以进行修改的。文字语言组织可能不是很清晰,如下图所示,一目了然的就知道说要表述的意思了。

  

三、关键字 static

  static,静态的。在 Java 中,static 通常可被用于修饰 变量、方法以及代码块。

  1、修饰变量

  static 修饰的变量,叫做静态变量。static 变量被所有类对象共享,在内存中仅一份,随着类的初始化而被加载。与之对应的非静态变量,是属于每个实例对象本身,内存中存在多份,相互间不影响。

  2、修饰方法

  static 修饰的方法,叫做静态方法。调用静态方法,不依赖于实例对象就可以进行访问,所以,静态方法是没有 this的。由于此特性以及非静态方法依赖于实例对象调用,所以静态方法中是不能够直接使用非静态的成员属性和方法。与之相反的是,非静态方法是可以直接访问使用静态成员变量和方法。同样的,静态方法也是没有 super 的。可以一句话总结下:由于 static 和具体的实例对象无关,而 this、super和具体的实例对象息息相关,所以,static 和 this、super 势如水火,一如白天与黑夜。

  3、修饰代码块

  static 修饰代码块,在类初始化加载的时候,会按照 static 块的顺序进行加载,并且,生命周期内,只加载一次。基于此特性,可以设计优化程序的性能,一些只需要一次性初始化加载的内容,就可以放在 static 块中进行。

  4、代码示例

package com.cfang;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class T4 {

    private static int a;
    private static int b;
    private static int c;

    static {
        log.info("init value a");
        a = 10;
    }

    {
        /**
         *     普通代码块,依赖于实例对象
         */
        log.info("init value c");
        c = 12;
    }

    public static void main(String[] args) {
        // -- 静态方法调用非静态
        /**
         *     不可直接访问
         */
//        sayHello1();
        new T4().sayHello1();

        // -- 静态方法直接调用
        sayHello();

        // -- 静态代码块初始化资源
        log.info("value a : {}", a);
        log.info("value b : {}", b);
        log.info("value c : {}", c);
    }

    private static void sayHello() {
        log.info("say hello");
    }

    private void sayHello1() {
        log.info("say hello1");
        // -- 非静态方法直接调用
        sayHello();
    }

    static {
        log.info("init value b");
        b = 11;
    }
}

  5、static 常见误区

package com.cfang;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class T5 {

    private static int a = 10;

    public static void main(String[] args) {
        new T5().printVal();

        //-- The field DemoCls01.b is not visible
        DemoCls01.b;
    }

    private void printVal() {
        int a = 11;
        log.info("value a : {}", this.a);
    }
}

@Data
class DemoCls01{
    private static int b;
}

  5.1、static 的 this

  上述代码中,最终运行 printVal 方法,输出的结果是 :value a : 10  。 其实这也很好理解: this 指代的当前对象,而通过 new T5().printVal() 调用的话,this 指代的就是当前新创建的实例对象,static 修饰的变量本身是被所有类对象所共享的,而 printVal 方法中 a 属于局部变量,跟 this 实例对象并没有关联。所以,输出的就是 10。

  5.2、static 与 可见性

  static 并不能改变变量或者方法的可见性。上述代码中,main 方法中,DemoCls01.b 会编译报错。

  5.3、static 与 局部变量

  Java规范中,明确说明了 :static 关键字不可修饰局部变量。

四、总结

  final 和 static ,联合使用修饰属性表示一旦给值,就不可修改,并且可以通过类名访问;修饰方法,表示该方法不能重写,可以在不new对象的情况下调用。

  突然想到,接口 interface 中,成员变量的默认修饰符为 public static final,方法的默认修饰符 public abstract 。

原文地址:https://www.cnblogs.com/eric-fang/p/11593570.html

时间: 2024-10-10 07:47:08

Java基础之final、static关键字的相关文章

java基础学习总结——static关键字

永不放弃,一切皆有可能!!! 只为成功找方法,不为失败找借口! java基础学习总结——static关键字 一.static关键字 原来一个类里面的成员变量,每new一个对象,这个对象就有一份自己的成员变量,因为这些成员变量都不是静态成员变量.对于static成员变量来说,这个成员变量只有一份,而且这一份是这个类所有的对象共享. 1.1.静态成员变量与非静态成员变量的区别 以下面的例子为例说明 1 package cn.galc.test; 2 3 public class Cat { 4 5

Java基础15-final、static关键字和Object类

一.final关键字 1.什么是final关键字 继承的出现提高了代码的复用性,并方便开发.但随之也有问题,有些类在描述完之后,不想被继承,或者有些类中的部分方法功能是固定的,不想让子类重写.可是当子类继承了这些特殊类之后,就可以对其中的方法进行重写,那怎么解决呢? 要解决上述的这些问题,需要使用到一个关键字final,final的意思为最终,不可变.final是个修饰符,它可以用来修饰类,类的成员,以及局部变量. 2.final的特点 ①修饰类不可以被继承,但可以继承其他类 ②final修饰的

Java基础语法 - 面向对象 - static 关键字

使用static关键字修饰的变量.常量和方法分别被称作静态变量.静态常量和静态方法,也被称作类的静态成员 静态变量 使用static修饰过的类变量称为静态变量 该变量需要使用类名.变量名进行调用,不能使用对象名/this进行调用 在类方法中不能定义与静态变量同名的局部变量 1 package mingri.chapter_6; 2 3 public class Pool { 4 5 public static int water = 0; // 定义一个静态变量 6 7 public void

java基础---17. 静态static关键字

1 static关键字概述 2 静态static关键字修饰成员变量 2.1 定义一个学生类 public class Student { private String name; private int age; static String room; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { r

java基础之final关键字

与final关键字相关的笔试题面试题也是一道必考题.而且对于final的实际应用非常广泛,在代码设计的时候,如果对此不够足够掌握,可能就会很难排查与此相关的异常. final的理论知识如下: final类型的成员变量初始化值: 1.声明时候直接赋值 2.构造方法中赋值,如果一个类中有多个构造方法,就要保证在每个构造方法中都要完成对final类型变量的初始化工作 3.静态final成员变量必须在声明时赋值,且不能在构造方法中赋值 4.final成员变量指的是引用不能改变,即该变量的引用不能在指向其

java基础知识回顾之关键字

其实java中的常用关键字并不多,总共加起来也没有多少个,具体见如下这张表: private,protect,public 在java中,在类,类的属性和累的方法前面加上一个修饰符来对其进行访问权限上的控制.除了使用private,protect,public之外, 还有一种是default情况,即使不加任何权限修饰符.关于这四中情况的权限差别见下表: 注意:default不是修饰符,他表示一种不加任何修饰符的情况. 这里,主要看一看static,instanceof,final关键字的含义和如

Java 基础:认识&理解关键字 native 实战篇

Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket 泥瓦匠初次遇见 navicat 是在 java.lang.Object 源码中的一个hashCode方法: 1 public native int hashCode(); 为什么有个navicat呢?这是我所要学习的地方.所以今天泥瓦匠想要总结下navicat. 一.认识 native 即 JNI,Java Native Interface 凡是一种语言,都希望是纯.比如解决某一个方案都喜欢就单单这

java基础面向对象之this关键字

java基础面向对象之this关键字 2017-02-14 this的核心概念: this关键字在java中表示当前对象. this关键字的主要用法: 在java中利用this关键字可以实现类属性的调用,类方法的调用,当前对象. 一.调用属性 1 class Book{ //Book类 2 private String title ; //title属性 3 private int price ; //price属性 4 5 public Book(String t , int p){ 6 ti

Java中this和static关键字及代码块

this: 可以使用this表示类中的属性------this.name=name 可以使用this强调调用的是本类的方法 可以使用this调用本类的构造方法------this();调用本类中无参构造方法 可以使用this表示当前对象(调用方法的对象)----最重要的用途 static: 声明属性---------属性则为全局变量 声明方法---------Person.setName("Tom");使用类名称调用static方法 普通代码块:直接在方法或是语句中定义的代码块 pub