java复习 14
1 静态static方法可以直接调用
在 Java 里,静态方法(static method)属于类,并非类的实例。这意味着可以直接通过类名调用静态方法,而不用先创建类的对象。下面为你介绍 Java 静态方法的关键特性和使用方式:
1. 定义与调用静态方法
java
public class MathUtils {// 静态方法:计算两数之和public static int add(int a, int b) {return a + b;}// 非静态方法:需要通过实例调用public int multiply(int a, int b) {return a * b;}public static void main(String[] args) {// 直接通过类名调用静态方法int sum = MathUtils.add(3, 5);System.out.println("Sum: " + sum); // 输出: 8// 非静态方法需要先创建实例MathUtils utils = new MathUtils();int product = utils.multiply(3, 5);System.out.println("Product: " + product); // 输出: 15}
}
2. 核心特性
- 属于类而非实例:静态方法可以直接通过类名调用,调用时无需创建类的对象。
- 不能使用实例成员:静态方法无法访问类的实例变量和实例方法,因为它们与具体的对象无关。不过,静态方法可以访问类的静态变量和静态方法。
- 常见用途:工具方法(如
Math.sqrt()
)、工厂方法、单例模式的实例获取方法等,都常使用静态方法。
3. 静态方法与实例方法的差异
对比项 | 静态方法(static) | 实例方法(非 static) |
---|---|---|
调用方式 | 类名。方法名 () | 对象实例。方法名 () |
是否依赖对象 | 否 | 是 |
能否访问实例成员 | 否 | 能 |
能否访问静态成员 | 能 | 能 |
4. 静态方法的使用场景
- 工具类方法:像
java.lang.Math
类中的sin()
、cos()
等方法。 - 工厂方法:用于创建对象实例,例如
java.util.Collections.unmodifiableList()
。 - 单例模式:获取单例实例的方法通常被定义为静态方法。
5. 注意要点
- 内存占用:静态方法和静态变量在类加载时就会被初始化,会一直占用内存,直到程序结束。
- 继承限制:静态方法可以被继承,但不能被重写(Override),不过可以被隐藏。
- 多线程安全:静态方法如果操作静态变量,需要考虑线程安全问题。
示例:静态工具类
java
public class StringUtils {// 判断字符串是否为空public static boolean isEmpty(String str) {return str == null || str.length() == 0;}// 反转字符串public static String reverse(String str) {return new StringBuilder(str).reverse().toString();}
}// 使用示例
public class Main {public static void main(String[] args) {System.out.println(StringUtils.isEmpty("")); // 输出: trueSystem.out.println(StringUtils.reverse("hello")); // 输出: olleh}
}
合理运用静态方法能够提升代码的复用性和可维护性,不过要留意避免过度使用,防止造成代码结构僵化。
2 接口中所有的方法都是抽象方法
在 Java 中,接口(interface) 的设计初衷是定义一组规范(契约),因此接口中的方法在 Java 8 之前默认都是抽象方法,且不需要显式使用abstract
关键字声明。不过,从 Java 8 开始,接口的功能得到了扩展,允许包含默认方法(default method) 和静态方法(static method),这些方法有具体的实现体。
1. Java 8 之前的接口(纯抽象方法)
在 Java 8 之前,接口中的所有方法必须是抽象的(没有方法体):
java
public interface MyInterface {void abstractMethod(); // 隐式为public abstract,无需显式声明
}
- 隐式修饰符:接口中的方法默认是
public abstract
,即使不写也会自动添加。
2. Java 8 及以后的接口扩展
Java 8 引入了默认方法和静态方法,允许接口包含具体实现:
java
public interface MyInterface {// 1. 抽象方法(仍可定义)void abstractMethod(); // 隐式为public abstract// 2. 默认方法(有方法体)default void defaultMethod() {System.out.println("默认方法的实现");}// 3. 静态方法(有方法体)static void staticMethod() {System.out.println("静态方法的实现");}
}
- 默认方法:使用
default
关键字声明,必须有方法体,实现类可以继承或重写。 - 静态方法:使用
static
关键字声明,必须有方法体,只能通过接口名调用(如MyInterface.staticMethod()
)。
3. 接口方法的分类总结
方法类型 | 是否必须抽象 | 是否有方法体 | 默认修饰符 | 调用方式 |
---|---|---|---|---|
抽象方法 | ✅ | ❌ | public abstract | 由实现类重写后调用 |
默认方法 | ❌ | ✅ | public default | 实现类对象直接调用 |
静态方法 | ❌ | ✅ | public static | 接口名直接调用(如I.static() ) |
4. Java 9 + 的私有方法
Java 9 进一步允许接口定义私有方法(包括静态和非静态),用于封装接口内部的实现逻辑:
java
public interface MyInterface {default void defaultMethod() {privateMethod(); // 调用私有方法}private void privateMethod() { // Java 9+ 允许System.out.println("私有方法的实现");}
}
5. 关键点澄清
- 接口中并非所有方法都是抽象的:Java 8 之后,接口可以包含默认方法和静态方法,它们有具体实现。
- 抽象方法仍是接口的核心:接口的主要目的仍是定义抽象行为,默认方法和静态方法只是增强功能。
- 实现类的要求:实现类必须重写接口中的所有抽象方法,但可以选择是否重写默认方法。
总结
- Java 8 之前:接口中所有方法必须是抽象的。
- Java 8 及以后:接口可以包含抽象方法、默认方法和静态方法,其中后两者有具体实现。
- Java 9 及以后:接口还可以包含私有方法,用于内部逻辑复用。
因此,“接口中所有的方法都是抽象方法” 这一说法在 Java 8 之前成立,但在 Java 8 及以后不成立。
3 -a[9]表示什么?
在编程语言中,-a[9]
表示对数组a
的第 10 个元素取负。
4 int a[2]={1,2}; java里面这么声明可以吗?
在 Java 中,你提供的数组声明语法是错误的,会导致编译失败。而在 C/C++ 里,这种声明方式是正确的。下面为你详细分析:
1. Java 中的正确与错误写法
❌ 错误写法(类似 C/C++ 的语法)
java
int a[2] = {1, 2}; // 错误!Java不支持这种语法
✅ 正确写法(Java 风格)
java
// 方式1:静态初始化(指定元素,长度由元素个数决定)
int[] a = {1, 2}; // 长度为2的数组// 方式2:动态初始化(指定长度,元素默认初始化为0)
int[] a = new int[2]; // 长度为2的数组,元素为[0, 0]
a[0] = 1;
a[1] = 2;// 方式3:动态初始化时赋值
int[] a = new int[]{1, 2}; // 等价于 {1, 2}
2. 错误原因分析
Java 和 C/C++ 的数组声明语法存在显著差异:
- C/C++:允许在方括号中指定数组长度,例如:
c
运行
int a[2] = {1, 2}; // C/C++正确
- Java:方括号必须紧跟类型,且静态初始化时不能显式指定长度(长度由元素个数自动决定)。
3. Java 数组声明规则
-
静态初始化:
int[] a = {1, 2};
- 无需指定长度,编译器会根据元素个数确定。
- 必须在声明时赋值,不能分开写(例如
int[] a; a = {1, 2};
是错误的)。
-
动态初始化:
int[] a = new int[2];
- 必须指定长度,元素会被初始化为默认值(数值类型为 0,引用类型为
null
)。
- 必须指定长度,元素会被初始化为默认值(数值类型为 0,引用类型为
4. Java 示例代码
java
public class Main {public static void main(String[] args) {// 正确:静态初始化int[] a = {1, 2};System.out.println(a.length); // 输出: 2// 正确:动态初始化int[] b = new int[2];b[0] = 1;b[1] = 2;System.out.println(b.length); // 输出: 2// 错误示例(编译失败)// int[] c[2] = {1, 2}; // 语法错误// int[] d = new int[2]{1, 2}; // 不能同时指定长度和元素}
}
总结
- Java 中不能使用
int a[2] = {1, 2};
,这种写法是 C/C++ 的语法。 - Java 的正确写法:
int[] a = {1, 2};
或int[] a = new int[2];
。 - 静态初始化和动态初始化是 Java 数组声明的两种主要方式,需根据场景选择合适的语法。