在 Java 接口中定义静态方法
本文列出了 Java 接口中静态方法的规则,并演示了如何定义它们以及为什么我们不能重写它们。 我们还将探讨 Java 8 之前的接口中没有静态方法的原因。
Java接口中的静态方法
在讨论 Java 接口中的静态方法之前,了解一个接口非常重要,该接口包含一个或多个在实现该接口的类中定义的抽象方法(没有主体的方法)。
请注意
,无论我们是否编写 public 修饰符,这些抽象方法都是公共方法。
示例代码:
public interface Messages {
//public & abstract
public void display();
}
public class Test implements Messages{
// implementation of abstract method
public void display() {
System.out.println("Hi! Welcome to the Jiyik");
}
public static void main(String[] args) {
Test test = new Test();
test.display();
}
}
输出:
Hi! Welcome to the Jiyik
请记住,名为 display()
的抽象方法是公共方法,我们必须实例化 Test 类才能执行 display()
方法。
另一方面,静态方法与定义它们的类本身相关联,我们不需要实例化类来使用这些静态方法。 从 Java 8 开始,我们现在可以拥有静态接口方法。
现在,我们有了一个完整的主体以及接口中该特定静态方法所需的所有指令。 请记住,静态方法只能在类级别访问,而不能在实例级别访问。
因此,我们可以按如下方式访问静态方法。
示例代码
public interface Messages {
//static method
static void display(){
System.out.println("Hello! Nice to meet you");
}
}
public class Test {
public static void main(String[] args) {
Messages.display();
}
}
输出:
Hello! Nice to meet you
问题是我们可以重写静态方法吗? 不,我们不能重写静态方法。 否则,我们会得到一个编译错误。
此外,我们无法通过实现类的实例调用它们,因为静态方法是隐藏的。 请参阅以下产生编译错误的示例。
示例代码:
public interface Messages {
static void display(){
System.out.println("Hello! Nice to meet you");
}
}
public class Test implements Messages{
@Override
public void display(){
System.out.println("Override");
}
public static void main(String[] args) {
Test test = new Test();
test.display();
}
}
以下是上述代码围栏产生的错误描述。
输出:
Test.java:25: error: method does not override or implement a method from a supertype
@Override
^
1 error
在接口中使用静态方法的重要性
在Java接口中使用静态方法可以得到以下好处。
- 接口的静态方法封装了我们不希望子类或子接口继承或覆盖的行为。
- Java 接口的这些静态方法对于开发不限于类的特定实现类型的可重用实用程序非常有用。
接口中静态方法的规则
以下部分显示了使用静态方法的上述优点的规则。
接口的默认方法保存默认行为的指令,并且实现类可以选择通过覆盖它或按原样继承它来提供更具体的指令。 与默认方法类似,静态方法包含其行为的主体(指令集),但正如我们之前所了解的,不允许实现类继承或覆盖其接口的静态方法。
在 Java 接口中使用静态方法的人应该记住以下规则。
- 这些方法必须有一个主体。
- 我们只能使用接口名称来执行这些静态方法。
- 这些方法必须在方法的声明中具有 static 修饰符。 如果不指定,则默认为公开。 请记住,如果我们愿意,我们也可以将它们设为私有。
- 它们不能调用其他抽象或默认方法。
- 子类或子接口不允许重写或继承这些静态方法。
现在,此时您的脑海中可能有两个问题。
- 为什么过去(Java 8 发布之前)我们不能使用静态方法?
- 为什么我们不能重写静态方法?
让我们找出这两个问题的答案。
Java 8 之前的接口中没有静态方法的原因
在 Java 8 发布之前,没有强有力的、主要的技术原因导致 Java 接口没有静态方法。这些静态方法被认为是小的语言更新或更改,然后有官方建议在 Java 7 中添加它,但后来由于一些复杂性而被放弃。
最后,在 Java 8 中,我们引入了接口中的静态方法。 从 Java 8 开始,我们还了解了具有默认实现的可重写实例函数/方法。
请记住,它们仍然不包含实例字段。 这些功能是 lambda 表达式支持的一部分,您可以在此处阅读(JSR 335 H 部分)。
无法重写静态方法的原因
静态方法在编译时解析。 动态调度对于编译器无法确定对象的具体类型的实例方法有意义; 因此,我们无法解析要调用的方法。
但是我们需要一个类来执行静态方法; 由于该特定类在编译时是静态已知的,因此不需要动态分派。
假设每个类都有一个哈希表,它将方法的签名(名称和参数类型)映射到实现该方法的实际代码段。 当VM尝试在实例上执行方法时,它会查询对象的类并在类表中查找所请求的签名。
如果找到方法体则调用它; 否则,重复查找即可获得该类的父类。 此过程将继续,直到找到方法或不再留下父类(这会产生 NoSuchMethodError)。
如果相应的表具有相同方法签名的子类和超类的条目,则将首先遇到子类的版本,并且永远不会使用超类的版本 - 这是覆盖。
假设我们跳过一个对象实例并从子类开始,解析可以按照上面给出的方式进行,为您提供一种可重写的静态方法。 请注意,此解决方案只能在编译时发生。
然而,我们知道编译器从已知的类开始,而不是等到运行时才查询未指定类型的对象以获取其类。 因此,重写静态方法是没有意义的。
相关文章
如何在 Java 中延迟几秒钟的时间
发布时间:2023/12/17 浏览次数:217 分类:Java
-
本篇文章主要介绍如何在 Java 中制造程序延迟。本教程介绍了如何在 Java 中制造程序延时,并列举了一些示例代码来了解它。
如何在 Java 中把 Hashmap 转换为 JSON 对象
发布时间:2023/12/17 浏览次数:187 分类:Java
-
它描述了允许我们将哈希图转换为简单的 JSON 对象的方法。本文介绍了在 Java 中把 Hashmap 转换为 JSON 对象的方法。我们将看到关于创建一个 hashmap,然后将其转换为 JSON 对象的详细例子。
如何在 Java 中按值排序 Map
发布时间:2023/12/17 浏览次数:171 分类:Java
-
本文介绍了如何在 Java 中按值对 Map 进行排序。本教程介绍了如何在 Java 中按值对 Map
进行排序,并列出了一些示例代码来理解它。
如何在 Java 中打印 HashMap
发布时间:2023/12/17 浏览次数:192 分类:Java
-
本帖介绍了如何在 Java 中打印 HashMap。本教程介绍了如何在 Java 中打印 HashMap 元素,还列举了一些示例代码来理解这个主题。
在 Java 中更新 Hashmap 的值
发布时间:2023/12/17 浏览次数:146 分类:Java
-
本文介绍了如何在 Java 中更新 HashMap 中的一个值。本文介绍了如何在 Java 中使用 HashMap 类中包含的两个方法-put() 和 replace() 更新 HashMap 中的值。
Java 中的 hashmap 和 map 之间的区别
发布时间:2023/12/17 浏览次数:79 分类:Java
-
本文介绍了 Java 中的 hashmap 和 map 接口之间的区别。本教程介绍了 Java 中 Map 和 HashMap 之间的主要区别。在 Java 中,Map 是用于以键值对存储数据的接口,
在 Java 中获取用户主目录
发布时间:2023/12/17 浏览次数:218 分类:Java
-
这篇文章向你展示了如何在 Java 中获取用户主目录。本教程介绍了如何在 Java 中获取用户主目录,并列出了一些示例代码以指导你完成该主题。
Java 中 size 和 length 的区别
发布时间:2023/12/17 浏览次数:179 分类:Java
-
这篇文章教你如何知道 Java 中大小和长度之间的区别。本教程介绍了 Java 中大小和长度之间的区别。我们还列出了一些示例代码以帮助你理解该主题。
Java 中的互斥锁
发布时间:2023/12/17 浏览次数:111 分类:Java
-
了解有关 Java 中互斥锁的一切,在计算机科学领域,互斥或互斥被称为并发控制的属性。每台计算机都使用称为线程的最小程序指令序列。有一次,计算机在一个线程上工作。为了更好地理解,