类和接口 - 优先考虑静态成员类

知识点:

1. 四种嵌套类。

2. 什么情况下该用哪种嵌套类。


1. 四种嵌套类

嵌套类,定义在另一个类的内部的类。四中嵌套类如下:

a.静态成员类

b.非静态成员类

c.局部类

d.匿名类


a.静态成员类

看下面代码,Inner就是静态成员类,定义在类内部,用static修饰,静态成员类内部可以访问外层类的静态成员。


class StaticInner {
    private static int a = 4;

    // 静态内部类
    public static class Inner {
    }
}

b.非静态成员类

看下面代码,Inner就是非静态成员类,定义在类内部,没有static修饰,非静态成员类可以访问外层类的静态成员和非静态成员。

class StaticInner {
    private static int a = 4;

    // 静态内部类
    public class Inner {
    }
}

c.局部类

看下面代码,Inner就是局部类,定义在方法内部,像局部变量不能用访问修饰符修饰。只能在方法中使用。

class LocalInner {
    int a = 1;

    public void doSomething() {
        // 局部内部类
        class Inner {
        }
    }
}

d.匿名类

看下面代码,下面是线程的匿名内部类,隐含的继承了Thread类,相当于没有名字的局部类

Thread t = new Thread() {
            public void run() {
            }
      }


2. 什么情况下该用哪种嵌套类。

先看你的类在哪里使用,方法里面使用用局部类或者匿名类。类里面使用用静态成员类或非静态成员类。后面按照下面需求看用哪一种类。

a.静态成员类 : 需要外层类实例的引用

b.非静态成员类 : 不需要外层类实例的引用


c.局部类 : 只在一个方法里面使用多次。

d.匿名类 : 只在一个方法里面使用一次。





<think> 我们正在比较接口常量(在接口中定义的常量)静态类常量(在中定义的静态常量)的区别与优势。 根据引用[1]引用[2],我们可以得到一些关键点: 1. 接口中定义的基本数据型默认为`static``final`,即静态常量(引用[1]第五点)。 2. 抽象(以及普通)中定义的静态成员变量也是`static`的,但需要显式声明`final`才能成为常量。 具体分析: 一、定义方式: - 接口常量:在接口中,成员变量默认为`public static final`,因此只需直接定义即可,例如: ```java public interface Constants { int MAX_VALUE = 100; } ``` - 静态类常量:在中,必须显式使用`static final`来定义,例如: ```java public class Constants { public static final int MAX_VALUE = 100; } ``` 二、访问方式: - 接口常量:由于是`public`的,可以通过接口名直接访问,例如:`Constants.MAX_VALUE`。 - 静态类常量:同样通过名访问,例如:`Constants.MAX_VALUE`。 三、区别与优势: 1. **实现方式**: - 接口常量:接口不能有实例字段,因此所有字段都是静态常量。但接口不能包含实现,所以常量必须在声明时初始化(引用[1]第二点第四点)。 - 静态类常量:中可以包含静态常量,也可以包含其他静态非静态的成员。常量可以在静态代码块中初始化(但常量要求必须在声明时或静态块中初始化,且只能赋值一次)。 2. **继承与多继承**: - 接口常量:接口支持多继承(引用[1]第三点),因此一个可以实现多个接口,从而同时拥有这些接口的常量。但是,如果多个接口中有同名的常量,会导致冲突(编译错误)。 - 静态类常量:不支持多继承,所以只能继承一个。因此,静态类常量不会因为多继承导致冲突,但扩展性不如接口。 3. **设计意图**: - 接口常量:通常用于定义一组相关的常量,这些常量被多个共享。例如,在API中定义错误码或状态码。 - 静态类常量:通常用于自身需要使用的常量,或者作为工具的常量(如`Math.PI`)。 4. **内存占用**: - 由于都是`static`的,两者在内存中都只有一份,存储在方法区中。 5. **使用建议**: - 如果常量是某个的固有属性(如`Integer.MAX_VALUE`),则放在中。 - 如果常量是通用的,与多个相关,且不依赖于某个具体,那么使用接口可能更合适。但要注意,使用接口定义常量有时会被认为是一种不好的做法,因为接口应该定义行为,而不是状态。因此,更推荐使用不可实例化的工具(私有构造器)来定义常量。 四、优势对比: - 接口常量的优势: - 编写简单,不需要写`public static final`。 - 可以被多个不同的实现使用,并且这些还可以实现其他接口- 在枚举型出现之前,常被用来实现枚举的效果。 - 静态类常量的优势: - 符合的封装原则,常量属于某个特定的,职责更清晰。 - 可以在中定义静态方法,配合常量使用,提供更丰富的操作。 - 避免接口的多继承导致的常量冲突问题。 五、现代实践: 由于接口中定义常量会使得接口承担了不属于它的职责(接口应该定义行为),因此现在更推荐使用枚举或工具(私有构造器)来定义常量。例如: ```java public final class AppConstants { private AppConstants() {} // 防止实例化 public static final int MAX_USER = 100; } ``` 总结: - 接口常量:简洁,多继承支持,但容易引发命名冲突,且不符合接口设计原则(仅定义行为)。 - 静态类常量:职责明确,避免冲突,更符合面向对象设计原则。 根据引用[4]中提到的“全盘责任委托”加载机制,静态常量的加载由加载器完成,而接口的常量也是静态的,因此加载机制似。 参考资料: [^1]: 接口中所有成员变量都是public static final的,而抽象则不是。 [^2]: 静态成员随着的加载而加载,优先于对象存在,且被所有对象共享。 §§相关问题§§ 1. 接口中定义常量有什么缺点? 2. 如何避免多个接口中同名常量冲突? 3. 枚举型与常量接口相比有什么优势? </think> ### 接口常量与静态类常量的区别与优势 #### **一、定义方式对比** | **特性** | **接口常量** | **静态类常量** | |------------------|-----------------------------------------------|-----------------------------------------------| | **语法** | 默认`public static final`(可省略修饰符) | 需显式声明`public static final` | | **示例** | `interface Config { int MAX_SIZE = 100; }` | `class Config { public static final int MAX_SIZE = 100; }` | | **初始化** | 必须在声明时初始化 | 可在声明时或静态代码块中初始化 | | **多继承支持** | ✅ 接口支持多继承(允许多个常量来源)[^1] | ❌ 不支持多继承 | #### **二、核心区别** 1. **设计目的** - **接口常量**:用于定义**跨实现的通用常量**(如API错误码),强调行为契约[^1]。 - **静态类常量**:用于**自身的专用常量**(如数学常数`Math.PI`),强调状态封装[^2]。 2. **内存机制** - 两者均为`static`,属于级别,在加载时初始化并存入方法区[^2]。 - 区别在于:接口常量通过**接口的符号引用**访问,静态类常量通过**的Class对象**访问。 3. **冲突处理** - **接口常量**:若多继承的接口包含同名常量,编译报错(需显式解决歧义)。 - **静态类常量**:无冲突风险(单继承)。 #### **三、优势分析** | **场景** | **推荐方案** | **优势** | |------------------------|------------------|--------------------------------------------------------------------------| | **跨组件共享常量** | 接口常量 | 统一管理多个实现的公共常量(如`HttpStatus.OK`)[^1] | | **工具专用常量** | 静态类常量 | 高内聚,避免污染全局命名空间(如`Integer.MAX_VALUE`)[^2] | | **需动态初始化的常量** | 静态类常量 | 可在静态代码块中计算(如`static { MAX = loadConfig(); }`) | | **避免魔法数字** | 两者均可 | 提高可读性,但接口常量更适用于多实现场景 | #### **四、代码示例** ```java // 接口常量:跨实现共享 public interface HttpStatus { int OK = 200; // 默认 public static final int NOT_FOUND = 404; } // 静态类常量:工具专用 public final class MathUtils { private MathUtils() {} // 防止实例化 public static final double PI = 3.1415926; static { /* 可在此初始化复杂常量 */ } } ``` #### **五、使用建议** 1. **优先静态类常量** 符合封装原则,避免接口承担超出其职责(定义行为)的功能[^1][^4]。 2. **接口常量适用场景** - 常量与接口行为强相关(如`Serializable`的`serialVersionUID`)。 - 需要被多个无关共享的全局常量。 3. **避免反模式** 不要创建**仅包含常量的接口**(如`ConstantsInterface`),应改用`final class + private constructor`[^4]。 > **关键结论**:接口常量强调**跨实现共享**,静态类常量强调**内封装**。现代Java开发中,更推荐用枚举或工具管理常量[^4]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值