一、总览:核心关键字分类
| 类型 | 关键字/修饰符 | 核心作用 | 通俗类比 |
|---|---|---|---|
| 访问修饰符 | public | 所有地方都能访问 | 家里的客厅(所有人可进) |
| protected | 本类+同包类+子类能访问 | 家里的书房(家人+亲戚可进) | |
| 默认(无修饰符) | 本类+同包类能访问 | 家里的卧室(只有家人可进) | |
| private | 只有本类能访问 | 家里的保险柜(只有自己能开) | |
| 特殊关键字 | static | 属于"类"而非"对象",全局共享 | 公司的公共打印机(所有人用同一台) |
| final | "最终的",不可变/不可继承/不可重写 | 盖章的合同(不能改) |
二、第一类:访问修饰符(控制"谁能访问")
访问修饰符的核心是控制类、方法、属性的可见范围,就像给代码加"权限锁",不同锁对应不同的访问权限,先看完整权限对比表:
| 修饰符 | 本类 | 同包类 | 子类(不同包) | 任意类(不同包) | 核心使用场景 |
|---|---|---|---|---|---|
| private | ✅ | ❌ | ❌ | ❌ | 类的内部属性/工具方法(对外隐藏) |
| 默认(无修饰) | ✅ | ✅ | ❌ | ❌ | 同包内的辅助类/方法(包内复用) |
| protected | ✅ | ✅ | ✅ | ❌ | 子类需要继承的方法/属性 |
| public | ✅ | ✅ | ✅ | ✅ | 对外提供的接口/方法(开放访问) |
1. private(私有)------ 仅本类可见
核心特点
只能在定义它的类内部访问,外部(哪怕是子类、同包类)都不能直接访问,是"最严格"的权限。
使用时机
-
类的私有属性 (比如
Student的name、age):对外隐藏,通过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(受保护)------ 本类+同包+子类可见
核心特点
权限比默认修饰符广,不同包的子类也能访问,但不同包的非子类不能访问。
使用时机
-
父类中需要让子类继承、重写,但又不想让外部任意类访问的方法/属性;
-
比如父类
Person的age属性,子类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(静态)------ 属于"类",而非"对象"
核心特点
-
归属不同:static修饰的变量/方法/代码块,属于「类本身」,而非「对象」;
-
全局共享:所有对象共用同一个static变量(改一个,全变);
-
调用方式 :可直接通过
类名.变量/方法调用,无需创建对象; -
生命周期:类加载时就初始化,比对象创建早,程序结束才销毁。
生活类比
公司的公共打印机(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)、不想被修改的变量 |
| 方法 | 不可被子类重写 | 不想被子类修改逻辑的核心方法(比如工具方法) |
| 类 | 不可被继承 | 工具类(比如Math、String)、不想被扩展的类 |
生活类比
-
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句话记牢核心)
-
访问修饰符管"谁能访问":
public全开放,private仅自己,protected给子类,默认只给同包; -
static管"归属":属于类,全局共享,不用创建对象就能用; -
final管"不可改":变量成常量,方法不能重写,类不能继承。
(注:文档部分内容由 AI 生成)