接口(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 虽然没有实现方法,但可以直接使用 DOMAINTOKEN

示例 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 变量

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

相关推荐
m0_74823317几秒前
C与C++:底层编程的六大核心共性
java·开发语言
坊钰5 分钟前
【Rabbit MQ】Rabbit MQ 介绍
java·rabbitmq
雀啼春13 分钟前
Java中的数据类型
java
80530单词突击赢22 分钟前
C++关联容器深度解析:set/map全攻略
java·数据结构·算法
兩尛29 分钟前
c++知识点1
java·开发语言·c++
ONE_PUNCH_Ge30 分钟前
Go 语言泛型
开发语言·后端·golang
舟舟亢亢31 分钟前
JVM复习笔记——下
java·jvm·笔记
rainbow688933 分钟前
Python学生管理系统:JSON持久化实战
java·前端·python
良许Linux43 分钟前
DSP的选型和应用
后端·stm32·单片机·程序员·嵌入式