接口(interface)中的常量和 类(class)中的常量的区别

接口(interface)中的常量 和 类(class)中的常量 的区别。

1、定义方式

1.1. 接口中的常量(interface constant)

ini 复制代码
public interface Config {
    // 不需要显式写 public static final
    String NAME = "A**";
    int MAX_COUNT = 100;
}

接口中定义的变量,默认就是 public static final,即使你不写,编译器也会自动加上。

  • public:公开访问
  • static:属于接口本身,不依赖实例
  • final:不可修改

1.2. 类中的常量(class constant)

arduino 复制代码
public class Config {
    // 必须显式声明 static final
    public static final String NAME = "A**";
    public static final int MAX_COUNT = 100;
}

类中必须显式写出 static final,否则就不是常量。

2、核心区别对比

特性 接口中的常量 类中的常量
修饰符是否可选 ✅ 隐式 public static final,可不写 ❌ 必须显式写 static final
访问方式 InterfaceName.CONSTANT ClassName.CONSTANT
是否可以修改 ❌ final,不可变 ❌ final,不可变
存储位置 方法区(元数据) 方法区(类静态变量)
继承行为 实现类自动继承常量 子类可以继承 public/protected
初始化时机 接口加载时初始化 类加载时初始化
性能 几乎无差别 几乎无差别
使用场景 定义公共配置、协议常量 定义类相关的常量、配置

3、代码示例

示例 1:接口常量的继承

typescript 复制代码
public interface AppConfig {
    String DOMAIN = "XX";
    String TOKEN = "....";
}

public class LoginService implements AppConfig {
    public void connect() {
        System.out.println("域名: " + DOMAIN); // 直接使用接口常量
    }
}

LoginService 虽然没有实现方法,但可以直接使用 DOMAIN 和 TOKEN。

示例 2:类常量的继承

scala 复制代码
public class AppConfig {
    public static final String ENV = "prod";
}
public class DatabaseConfig extends AppConfig {
    public void printEnv() {
        System.out.println("环境: " + ENV); // 继承父类常量
    }
}

类通过继承获得常量。

4、注意:

1. 接口常量是"隐式 public static final"

ini 复制代码
interface BadExample {
    final String NAME = "Alice";        // ❌ 冗余,final 可省略
    static int COUNT = 10;              // ❌ 冗余
    // private String SECRET = "...";   // ❌ 编译错误!接口常量必须是 public
}

2. 接口不能有"实例常量"

  • 不能有实例变量和实例常量(包括常量)
  • 所有字段必须是 public static final(即:类常量)
  • 接口不能被实例化,所以"实例"相关的概念都不存在
java 复制代码
interface BadExample {
    final String name = "Alice"; // ✅ 可以,但它是 static final(接口常量)
    
    // String instanceValue; // ❌ 错误!接口不能有实例变量
}

3. 接口常量会类常量必须在声明时初始化(因为final修饰)

ini 复制代码
interface Config {
    // String NAME; // ❌ 编译错误!必须赋值
    String NAME = "Alice"; // ✅
}

5、使用建议

场景 推荐方式
定义一组公共配置(如 API 地址、状态码) ✅ 使用 interface 常量(简洁)
常量与某个类强相关(如 Math.PI) ✅ 使用 class 常量
常量需要封装逻辑(如通过方法计算) ✅ 使用 class + 私有构造

6、什么是"实例常量"?

"实例常量"指的是:

  • 使用 final 修饰的成员变量
  • 属于对象实例(而不是类)
  • 每个对象可以有不同的值
  • 一旦创建后不可修改

示例:定义实例常量

arduino 复制代码
public class Person {
    // 实例常量:每个 Person 对象都有自己的 name 和 id
    private final String name;
    private final long id;

    // 构造函数中初始化
    public Person(String name, long id) {
        this.name = name;
        this.id = id;
    }

    // 只有 getter,没有 setter(因为是常量)
    public String getName() {
        return name;
    }

    public long getId() {
        return id;
    }
}

使用:

ini 复制代码
Person p1 = new Person("Alice", 1L);
Person p2 = new Person("Bob", 2L);

// p1.name = "Charlie"; // ❌ 编译错误!不能修改 final 变量

name 和 id 就是典型的"实例常量"------每个对象有自己的值,且创建后不可变。

相关推荐
学长毕设23 分钟前
基于SpringBoot的游乐园管理系统-附源码
java·spring boot·后端
橙序员小站34 分钟前
Windows 安装包反复报错?一次排查补上了 5 个 CI 检查点
后端
陈随易39 分钟前
Cloudflare 出钱,Vite 团队挑人,44 个维护者分 30 万美元
前端·后端·程序员
SimonKing1 小时前
震惊:怎么回事,opencode一轮对话耗尽免费额度
java·后端·程序员
装不满的克莱因瓶1 小时前
【SpringAI Alibaba】ReactAgent响应SSE实时流式传输案例实战
java·人工智能·ai·sse·springai
杨凯凡1 小时前
Spring Boot 文件上传怎么做才安全?流式落盘、路径校验与数据库一致性实战
java·spring boot·文件上传·后端安全·数据库一致性
张彦峰ZYF1 小时前
功能齐了不等于能上线:智能工单系统的AI回归测试、安全防护、成本可观测与CI/CD生产部署
后端·企业智能工单系统·评测线·安全线·成本线·部署线
这个昵称不容易1 小时前
旅游管理系统的设计与实现(SpringBoot + MySQL + Vue 前后端分离)
java·springboot·毕设
Rain的Java大神之路1 小时前
LeetCode 37 解数独面试攻略:回溯 + 位掩码 + MRV,从暴力到毫秒级求解
java·后端·leetcode
量化分析码农2 小时前
【Python量化波动率实战 05】你的组合真的分散了吗:滚动相关与分散化收益
后端