default 关键字
概述
default
关键字在Java中有两个主要用途:
- 在switch语句中作为默认分支,当所有case都不匹配时执行
- 在接口中定义默认方法(Java 8+)
语法格式
// switch语句中的default
switch (表达式) {
case 值1:
// 代码
break;
default:
// 默认代码
}
// 接口中的默认方法
interface InterfaceName {
default returnType methodName() {
// 默认实现
}
}
switch中的default
public class DefaultSwitchExample {
// 基本default使用
public static void processGrade(char grade) {
switch (grade) {
case 'A':
System.out.println("优秀");
break;
case 'B':
System.out.println("良好");
break;
case 'C':
System.out.println("中等");
break;
case 'D':
System.out.println("及格");
break;
case 'F':
System.out.println("不及格");
break;
default:
System.out.println("无效等级: " + grade);
}
}
// 数字范围处理
public static void categorizeNumber(int number) {
switch (number / 10) {
case 0:
System.out.println(number + " 在 0-9 范围内");
break;
case 1:
System.out.println(number + " 在 10-19 范围内");
break;
case 2:
System.out.println(number + " 在 20-29 范围内");
break;
case 3:
System.out.println(number + " 在 30-39 范围内");
break;
default:
if (number < 0) {
System.out.println(number + " 是负数");
} else {
System.out.println(number + " 大于等于40");
}
}
}
// 月份天数(default处理无效月份)
public static int getDaysInMonth(int month) {
switch (month) {
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
return 31;
case 4: case 6: case 9: case 11:
return 30;
case 2:
return 28; // 简化处理,不考虑闰年
default:
System.out.println("无效的月份: " + month);
return -1;
}
}
public static void main(String[] args) {
System.out.println("=== 成绩等级处理 ===");
processGrade('A');
processGrade('B');
processGrade('X'); // 触发default
System.out.println("\n=== 数字分类 ===");
categorizeNumber(5);
categorizeNumber(15);
categorizeNumber(25);
categorizeNumber(-10); // 触发default
categorizeNumber(50); // 触发default
System.out.println("\n=== 月份天数 ===");
for (int i = 1; i <= 13; i++) {
int days = getDaysInMonth(i);
if (days > 0) {
System.out.println("第" + i + "月有" + days + "天");
}
}
}
}
接口默认方法
// 定义带默认方法的接口
interface Drawable {
// 抽象方法
void draw();
// 默认方法
default void setColor(String color) {
System.out.println("设置颜色为: " + color);
}
default void displayInfo() {
System.out.println("这是一个可绘制的对象");
System.out.println("支持的操作: 绘制、设置颜色");
}
default double calculateArea() {
System.out.println("未实现面积计算");
return 0.0;
}
}
interface Movable {
void move(int x, int y);
default void moveBy(int deltaX, int deltaY) {
System.out.println("相对移动: (" + deltaX + ", " + deltaY + ")");
// 这里可以调用抽象方法
// move(getCurrentX() + deltaX, getCurrentY() + deltaY);
}
default void reset() {
System.out.println("重置位置到原点");
move(0, 0);
}
}
// 实现类
class Circle implements Drawable, Movable {
private double radius;
private int x, y;
public Circle(double radius) {
this.radius = radius;
this.x = 0;
this.y = 0;
}
@Override
public void draw() {
System.out.println("绘制半径为 " + radius + " 的圆形在位置 (" + x + ", " + y + ")");
}
@Override
public void move(int x, int y) {
this.x = x;
this.y = y;
System.out.println("圆形移动到位置 (" + x + ", " + y + ")");
}
// 重写默认方法
@Override
public double calculateArea() {
double area = Math.PI * radius * radius;
System.out.println("圆形面积: " + String.format("%.2f", area));
return area;
}
// 可以选择不重写其他默认方法,直接使用接口提供的实现
}
class Rectangle implements Drawable {
private double width, height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public void draw() {
System.out.println("绘制 " + width + "x" + height + " 的矩形");
}
@Override
public double calculateArea() {
double area = width * height;
System.out.println("矩形面积: " + area);
return area;
}
// 使用接口的默认setColor和displayInfo方法
}
public class DefaultMethodExample {
public static void main(String[] args) {
Circle circle = new Circle(5.0);
Rectangle rectangle = new Rectangle(10.0, 6.0);
System.out.println("=== 圆形操作 ===");
circle.draw();
circle.setColor("红色"); // 使用默认方法
circle.displayInfo(); // 使用默认方法
circle.calculateArea(); // 使用重写的方法
circle.move(10, 20);
circle.moveBy(5, 5); // 使用默认方法
circle.reset(); // 使用默认方法
System.out.println("\n=== 矩形操作 ===");
rectangle.draw();
rectangle.setColor("蓝色"); // 使用默认方法
rectangle.displayInfo(); // 使用默认方法
rectangle.calculateArea(); // 使用重写的方法
}
}
默认方法的冲突解决
interface InterfaceA {
default void commonMethod() {
System.out.println("InterfaceA的默认实现");
}
default void methodA() {
System.out.println("方法A");
}
}
interface InterfaceB {
default void commonMethod() {
System.out.println("InterfaceB的默认实现");
}
default void methodB() {
System.out.println("方法B");
}
}
// 实现多个接口时的冲突解决
class ConflictResolver implements InterfaceA, InterfaceB {
// 必须重写冲突的方法
@Override
public void commonMethod() {
System.out.println("ConflictResolver的实现");
// 可以选择调用特定接口的默认方法
InterfaceA.super.commonMethod();
InterfaceB.super.commonMethod();
}
// 非冲突的默认方法可以直接使用
// methodA() 和 methodB() 可以直接使用
}
// 另一种解决方案:选择其中一个接口的实现
class ConflictResolver2 implements InterfaceA, InterfaceB {
@Override
public void commonMethod() {
// 选择使用InterfaceA的实现
InterfaceA.super.commonMethod();
}
}
public class DefaultMethodConflictExample {
public static void main(String[] args) {
System.out.println("=== 冲突解决方案1 ===");
ConflictResolver resolver1 = new ConflictResolver();
resolver1.commonMethod();
resolver1.methodA();
resolver1.methodB();
System.out.println("\n=== 冲突解决方案2 ===");
ConflictResolver2 resolver2 = new ConflictResolver2();
resolver2.commonMethod();
resolver2.methodA();
resolver2.methodB();
}
}
实际应用示例
import java.util.*;
import java.util.function.Predicate;
// 数据处理接口
interface DataProcessor<T> {
// 抽象方法
List<T> process(List<T> data);
// 默认过滤方法
default List<T> filter(List<T> data, Predicate<T> condition) {
List<T> result = new ArrayList<>();
for (T item : data) {
if (condition.test(item)) {
result.add(item);
}
}
System.out.println("过滤前: " + data.size() + " 项,过滤后: " + result.size() + " 项");
return result;
}
// 默认排序方法
default List<T> sort(List<T> data, Comparator<T> comparator) {
List<T> result = new ArrayList<>(data);
result.sort(comparator);
System.out.println("数据已排序");
return result;
}
// 默认统计方法
default void printStatistics(List<T> data) {
System.out.println("数据统计:");
System.out.println(" 总数量: " + data.size());
System.out.println(" 是否为空: " + data.isEmpty());
if (!data.isEmpty()) {
System.out.println(" 第一项: " + data.get(0));
System.out.println(" 最后一项: " + data.get(data.size() - 1));
}
}
}
// 数字处理器
class NumberProcessor implements DataProcessor<Integer> {
@Override
public List<Integer> process(List<Integer> data) {
System.out.println("处理数字数据...");
List<Integer> result = new ArrayList<>();
for (Integer num : data) {
if (num != null) {
result.add(num * 2); // 数字乘以2
}
}
return result;
}
// 可以添加特定的方法
public List<Integer> filterEven(List<Integer> data) {
return filter(data, num -> num % 2 == 0);
}
public List<Integer> sortAscending(List<Integer> data) {
return sort(data, Integer::compareTo);
}
}
// 字符串处理器
class StringProcessor implements DataProcessor<String> {
@Override
public List<String> process(List<String> data) {
System.out.println("处理字符串数据...");
List<String> result = new ArrayList<>();
for (String str : data) {
if (str != null && !str.trim().isEmpty()) {
result.add(str.trim().toUpperCase());
}
}
return result;
}
public List<String> filterByLength(List<String> data, int minLength) {
return filter(data, str -> str.length() >= minLength);
}
public List<String> sortByLength(List<String> data) {
return sort(data, Comparator.comparing(String::length));
}
}
public class DefaultMethodApplicationExample {
public static void main(String[] args) {
// 数字处理示例
System.out.println("=== 数字处理 ===");
NumberProcessor numberProcessor = new NumberProcessor();
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
System.out.println("原始数据: " + numbers);
numberProcessor.printStatistics(numbers); // 使用默认方法
List<Integer> processedNumbers = numberProcessor.process(numbers);
System.out.println("处理后: " + processedNumbers);
List<Integer> evenNumbers = numberProcessor.filterEven(processedNumbers);
System.out.println("偶数: " + evenNumbers);
List<Integer> sortedNumbers = numberProcessor.sortAscending(Arrays.asList(9, 3, 7, 1, 5));
System.out.println("排序后: " + sortedNumbers);
// 字符串处理示例
System.out.println("\n=== 字符串处理 ===");
StringProcessor stringProcessor = new StringProcessor();
List<String> strings = Arrays.asList("hello", "world", "java", "programming", "default", "method");
System.out.println("原始数据: " + strings);
stringProcessor.printStatistics(strings); // 使用默认方法
List<String> processedStrings = stringProcessor.process(strings);
System.out.println("处理后: " + processedStrings);
List<String> longStrings = stringProcessor.filterByLength(strings, 5);
System.out.println("长度>=5的字符串: " + longStrings);
List<String> sortedByLength = stringProcessor.sortByLength(strings);
System.out.println("按长度排序: " + sortedByLength);
}
}
最佳实践
public class DefaultBestPractices {
// 1. switch中的default应该处理所有未预期的情况
public static String getHttpStatusMessage(int statusCode) {
switch (statusCode) {
case 200:
return "OK";
case 201:
return "Created";
case 400:
return "Bad Request";
case 401:
return "Unauthorized";
case 404:
return "Not Found";
case 500:
return "Internal Server Error";
default:
// 好的做法:提供有意义的默认处理
return "Unknown Status Code: " + statusCode;
}
}
// 2. 接口默认方法应该提供合理的默认实现
interface Cache<K, V> {
V get(K key);
void put(K key, V value);
// 好的默认方法:提供常用功能的默认实现
default boolean containsKey(K key) {
return get(key) != null;
}
default V getOrDefault(K key, V defaultValue) {
V value = get(key);
return value != null ? value : defaultValue;
}
default void putIfAbsent(K key, V value) {
if (!containsKey(key)) {
put(key, value);
}
}
// 好的默认方法:提供工具方法
default void printStats() {
System.out.println("缓存统计信息");
// 默认实现可以调用抽象方法
}
}
// 3. 避免在default中添加复杂逻辑
interface Service {
void start();
void stop();
// 好的做法:简单的默认实现
default boolean isRunning() {
return false; // 简单的默认返回值
}
// 好的做法:组合其他方法
default void restart() {
stop();
start();
}
// 避免:复杂的业务逻辑
/*
default void complexOperation() {
// 大量复杂的业务逻辑...
// 这样的逻辑应该放在实现类中
}
*/
}
// 4. switch的default位置
public static void processOption(int option) {
switch (option) {
case 1:
System.out.println("选项1");
break;
case 2:
System.out.println("选项2");
break;
case 3:
System.out.println("选项3");
break;
default: // 通常放在最后
System.out.println("无效选项: " + option);
break;
}
}
public static void main(String[] args) {
System.out.println("=== HTTP状态码 ===");
System.out.println("200: " + getHttpStatusMessage(200));
System.out.println("404: " + getHttpStatusMessage(404));
System.out.println("999: " + getHttpStatusMessage(999)); // 触发default
System.out.println("\n=== 选项处理 ===");
processOption(1);
processOption(2);
processOption(99); // 触发default
}
}
default关键字在switch语句中提供了重要的错误处理机制,在接口中则支持了向后兼容的功能扩展。