【Java面试】Java核心关键字解析(static_final_访问修饰符)小白易懂

一、总览:核心关键字分类

类型 关键字/修饰符 核心作用 通俗类比
访问修饰符 public 所有地方都能访问 家里的客厅(所有人可进)
protected 本类+同包类+子类能访问 家里的书房(家人+亲戚可进)
默认(无修饰符) 本类+同包类能访问 家里的卧室(只有家人可进)
private 只有本类能访问 家里的保险柜(只有自己能开)
特殊关键字 static 属于"类"而非"对象",全局共享 公司的公共打印机(所有人用同一台)
final "最终的",不可变/不可继承/不可重写 盖章的合同(不能改)

二、第一类:访问修饰符(控制"谁能访问")

访问修饰符的核心是控制类、方法、属性的可见范围,就像给代码加"权限锁",不同锁对应不同的访问权限,先看完整权限对比表:

修饰符 本类 同包类 子类(不同包) 任意类(不同包) 核心使用场景
private 类的内部属性/工具方法(对外隐藏)
默认(无修饰) 同包内的辅助类/方法(包内复用)
protected 子类需要继承的方法/属性
public 对外提供的接口/方法(开放访问)

1. private(私有)------ 仅本类可见

核心特点

只能在定义它的类内部访问,外部(哪怕是子类、同包类)都不能直接访问,是"最严格"的权限。

使用时机

  • 类的私有属性 (比如Studentnameage):对外隐藏,通过get/set方法访问,保证数据安全;

  • 类的内部工具方法(只给本类其他方法调用,对外无需暴露)。

代码示例

java 复制代码
/**
 * private使用示例:学生类的私有属性
 */
class Student {
    // 私有属性:只能本类访问
    private String name;
    private int age;
    
    // 对外提供访问方法(get/set)
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    // 私有方法:仅本类内部调用
    private void checkAge() {
        if (age < 0) {
            age = 0;
        }
    }
}

public class PrivateDemo {
    public static void main(String[] args) {
        Student s = new Student();
        // s.name = "张三"; // 报错!private属性,外部不能直接访问
        s.setName("张三"); // 只能通过public方法访问
        System.out.println(s.getName()); // 输出:张三
    }
}

2. 默认修饰符(无关键字)------ 同包可见

核心特点

不加任何修饰符时,只能在本类 + 同一个包下的类访问,不同包的子类/类都不能访问。

使用时机

  • 包内的辅助类、工具方法(只给同包内的类用,不用对外暴露);

  • 不想让其他包访问,但包内需要复用的代码。

代码示例(分两个同包类)

java 复制代码
// 包:com.demo(两个类在同一个包下)
// 类1:DefaultDemo(默认修饰的方法)
class DefaultDemo {
    // 默认修饰的方法:同包可见
    void sayHello() {
        System.out.println("同包内可以访问的方法");
    }
}

// 类2:TestDefault(同包,可访问)
public class TestDefault {
    public static void main(String[] args) {
        DefaultDemo demo = new DefaultDemo();
        demo.sayHello(); // 正常运行,输出:同包内可以访问的方法
    }
}

// 若TestDefault在其他包(比如com.other),则demo.sayHello()会报错!

3. protected(受保护)------ 本类+同包+子类可见

核心特点

权限比默认修饰符广,不同包的子类也能访问,但不同包的非子类不能访问。

使用时机

  • 父类中需要让子类继承、重写,但又不想让外部任意类访问的方法/属性;

  • 比如父类Personage属性,子类Student需要访问,但外部类不能直接改。

代码示例(不同包子类)

java 复制代码
// 包1:com.parent
package com.parent;
// 父类:Person
public class Person {
    protected int age = 18; // 受保护属性
}

// 包2:com.child(不同包)
package com.child;
import com.parent.Person;
// 子类:Student(不同包,可访问protected属性)
public class Student extends Person {
    public void printAge() {
        System.out.println("父类的age:" + age); // 正常访问
    }
}

// 包2:TestProtected(不同包,非子类,不能访问)
public class TestProtected {
    public static void main(String[] args) {
        Person p = new Person();
        // System.out.println(p.age); // 报错!不同包非子类,不能访问protected
        Student s = new Student();
        s.printAge(); // 正常运行,输出:父类的age:18
    }
}

4. public(公开)------ 所有地方可见

核心特点

权限最宽松,**任何地方(不同类、不同包、不同项目)**都能访问。

使用时机

  • 对外提供的接口、方法(比如工具类的核心方法、框架的API);

  • 需要被其他包、其他类调用的核心功能;

  • 注意:不要把所有内容都设为public,会暴露内部逻辑,增加安全风险。

代码示例

java 复制代码
// 包1:com.api
package com.api;
// 公开的工具类
public class PublicTool {
    // 公开方法:所有地方可调用
    public static int add(int a, int b) {
        return a + b;
    }
}

// 包2:com.test
package com.test;
import com.api.PublicTool;
// 不同包,可访问public方法
public class TestPublic {
    public static void main(String[] args) {
        int result = PublicTool.add(10, 20);
        System.out.println(result); // 输出:30
    }
}

三、第二类:特殊关键字(static/final)------ 控制"特性"

(一)static(静态)------ 属于"类",而非"对象"

核心特点

  1. 归属不同:static修饰的变量/方法/代码块,属于「类本身」,而非「对象」;

  2. 全局共享:所有对象共用同一个static变量(改一个,全变);

  3. 调用方式 :可直接通过类名.变量/方法调用,无需创建对象;

  4. 生命周期:类加载时就初始化,比对象创建早,程序结束才销毁。

生活类比

公司的公共打印机(static)------ 所有员工(对象)都用同一台,改打印机设置(改static变量),所有员工都受影响;而员工的私人水杯(非static),每个员工(对象)都有自己的,互不影响。

核心使用场景

static修饰的内容 使用时机 示例
静态变量 全局常量、统计数据(比如计数)、工具类属性 public static final int MAX_AGE = 100
静态方法 工具类方法(无需创建对象)、通用功能 Math.abs()Arrays.sort()
静态代码块 类加载时初始化静态资源(比如加载配置) 初始化静态变量

代码示例(静态变量+方法+代码块)

java 复制代码
/**
 * static关键字完整示例:统计创建的对象数量
 */
public class StaticDemo {
    // 静态变量:全局共享,统计对象数量
    public static int count = 0;
    
    // 静态代码块:类加载时执行(只执行一次)
    static {
        System.out.println("静态代码块执行:初始化count为0");
        count = 0;
    }
    
    // 构造方法:创建对象时执行,count+1
    public StaticDemo() {
        count++;
    }
    
    // 静态方法:直接通过类名调用,打印count
    public static void printCount() {
        System.out.println("已创建的对象数量:" + count);
    }
    
    public static void main(String[] args) {
        // 直接调用静态方法(无需创建对象)
        StaticDemo.printCount(); // 输出:已创建的对象数量:0
        
        // 创建对象,count自动+1
        new StaticDemo();
        new StaticDemo();
        
        // 直接访问静态变量
        System.out.println("静态变量count:" + StaticDemo.count); // 输出:2
        // 调用静态方法
        StaticDemo.printCount(); // 输出:已创建的对象数量:2
    }
}

运行结果

plaintext 复制代码
静态代码块执行:初始化count为0
已创建的对象数量:0
静态变量count:2
已创建的对象数量:2

(二)final(最终)------ 不可变/不可继承/不可重写

核心特点

final的核心是"不可修改",修饰不同内容,规则不同:

修饰内容 核心规则 使用时机
变量 赋值后不可改(常量),局部变量可先声明后赋值,成员变量必须初始化 定义常量(比如MAX_AGE)、不想被修改的变量
方法 不可被子类重写 不想被子类修改逻辑的核心方法(比如工具方法)
不可被继承 工具类(比如MathString)、不想被扩展的类

生活类比

  • final变量:盖章的合同(一旦签字,不能改);

  • final方法:公司的核心流程(不能被员工修改);

  • final类:成品的工具(比如锤子,不用再改造)。

代码示例(final变量+方法+类)

java 复制代码
/**
 * final关键字完整示例
 */
// final类:不可被继承(比如String就是final类)
final class FinalClass {
    // final变量:常量(大写命名)
    public static final int MAX_SCORE = 100;
    
    // final方法:不可被重写
    public final void sayHello() {
        System.out.println("final方法,不能被重写");
    }
}

// class SubClass extends FinalClass {} // 报错!final类不能被继承

public class FinalDemo {
    public static void main(String[] args) {
        // final局部变量:赋值后不可改
        final int a = 10;
        // a = 20; // 报错!final变量不能修改
        
        // final成员变量示例
        FinalClass demo = new FinalClass();
        System.out.println(demo.MAX_SCORE); // 输出:100
        // demo.MAX_SCORE = 90; // 报错!final变量不能修改
        
        // final方法:不能被重写
        demo.sayHello(); // 输出:final方法,不能被重写
    }
}

四、面试高频考点(直接背,不踩坑)

考点1:访问修饰符的权限范围(从宽到窄)?

答:public >protected > 默认(无修饰) > private

考点2:static和实例变量的区别?

答:static变量属于类,全局共享,一个类只有一份;实例变量属于对象,每个对象有自己的副本,互不影响。

考点3:final修饰变量的注意点?

答:final变量赋值后不可改;成员变量(类的属性)必须初始化(声明时/构造方法/静态代码块),局部变量可先声明后赋值。

考点4:static方法里能调用非static方法/变量吗?

答:不能!static方法属于类,执行时可能还没有对象;非static方法/变量属于对象,必须创建对象才能调用。

考点5:private方法能被重写吗?

答:不能!private方法仅本类可见,子类根本访问不到,自然无法重写(哪怕子类写了同名方法,也不是重写)。

五、小白总结(3句话记牢核心)

  1. 访问修饰符管"谁能访问":public全开放,private仅自己,protected给子类,默认只给同包;

  2. static管"归属":属于类,全局共享,不用创建对象就能用;

  3. final管"不可改":变量成常量,方法不能重写,类不能继承。

(注:文档部分内容由 AI 生成)

相关推荐
小飞学编程...2 小时前
【Java相关八股文(一)】
android·java·开发语言
毅炼2 小时前
Java 基础常见问题总结(5)
java·后端
前路不黑暗@2 小时前
Java项目:Java脚手架项目的通用组件的封装(七)
java·开发语言·spring boot·后端·学习·spring cloud·maven
xj198603192 小时前
Java进阶-在Ubuntu上部署SpringBoot应用
java·spring boot·ubuntu
Coder_Boy_2 小时前
从单体并发工具类到分布式并发:思想演进与最佳实践(二)
java·spring boot·分布式·微服务·设计模式
Web打印2 小时前
Phpask(php集成环境)之04配置网站
开发语言·前端·php
可涵不会debug2 小时前
时序数据库选型指南:Apache IoTDB深度解析与对比
java·后端·struts
郝学胜-神的一滴2 小时前
深入浅出链表:数据结构中的“珍珠项链“
开发语言·数据结构·程序人生·链表
源力祁老师2 小时前
Odoo ORM 将 Python 查询意图编译为 SQL 的逐函数讲解(Odoo 19)
java·服务器·数据库