返回顶部
首页 > 资讯 > 精选 >Java程序员必须掌握的注解有哪些
  • 552
分享到

Java程序员必须掌握的注解有哪些

2023-06-17 02:06:00 552人浏览 独家记忆
摘要

这篇文章主要讲解了“Java程序员必须掌握的注解有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java程序员必须掌握的注解有哪些”吧!划重点自 jdk5 推出以来,注解已成为Java生

这篇文章主要讲解了“Java程序员必须掌握的注解有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java程序员必须掌握的注解有哪些”吧!

划重点

jdk5 推出以来,注解已成为Java生态系统不可缺少的一部分。虽然开发者为Java框架(例如spring的@Autowired)开发了无数的自定义注解,但编译器认可的一些注解非常重要。

在本文中,我们将看到5个Java编译器支持的注解,并了解其期望用途。顺便,我们将探索其创建背后的基本原理,围绕其用途的一些特质,以及正确应用的一些例子。虽然其中有些注解比其他注解更为常见,但非初学Java开发人员都应该消化了解每个注解。

  • @Override

  • @FunctionalInterface

  • @SuppressWarnings

  • @SafeVarargs

  • @Deprecated

首先,我们将深入研究Java中最常用的注解之一:@Override。

@Override

覆盖方法的实现或为抽象方法提供实现的能力是任何面向对象(OO)语言的核心。由于Java是OO语言,具有许多常见的面向对象的抽象机制,所以在非***超类定义的非最终方法或接口中的任何方法(接口方法不能是最终的)都可以被子类覆盖。点击这里阅读 Java 10 新特性实战教程

虽然开始时覆盖方法看起来很简单,但是如果执行不正确,则可能会引入许多微小的bug。例如,用覆盖类类型的单个参数覆盖Object#equals方法就是一种常见的错误:

public class Foo {    public boolean equals(Foo foo) {        // Check if the supplied object is equal to this object      }  }

由于所有类都隐式地从Object类继承,Foo类的目的是覆盖Object#equals方法,因此Foo可被测试是否与Java中的任何其他对象相等。虽然我们的意图是正确的,但我们的实现则并非如此。

实际上,我们的实现根本不覆盖Object#equals方法。相反,我们提供了方法的重载:我们不是替换Object类提供的equals方法的实现,而是提供第二个方法来专门接受Foo对象,而不是Object对象。

我们的错误可以用简单实现来举例说明,该实现对所有的相等检查都返回true,但当提供的对象被视为Object(Java将执行的操作,例如在Java Collections Framework即JCF中)时,就永远不会调用它:

public class Foo {    public boolean equals(Foo foo) {        return true;      }  }  Object foo = new Foo();  Object identicalFoo = new Foo();  System.out.println(foo.equals(identicalFoo));    // false

这是一个非常微妙但常见的错误,可以被编译器捕获。我们的意图是覆盖Object#equals方法,但因为我们指定了一个类型为Foo而不是Object类型的参数,所以我们实际上提供了重载的Object#equals方法,而不是覆盖它。为了捕获这种错误,我们引入@Override注解,它指示编译器检查覆盖实际有没有执行。如果没有执行有效的覆盖,则会抛出错误。因此,我们可以更新Foo类,如下所示:

public class Foo {    @Override      public boolean equals(Foo foo) {        return true;  }  }

如果我们尝试编译这个类,我们现在收到以下错误:

$ javac Foo.java  Foo.java:3: error: method does not override or implement a method from a supertype          @Override          ^1 error

实质上,我们已经将我们已经覆盖方法的这一隐含的假设转变为由编译器进行的显性验证。如果我们的意图被错误地实现,那么Java编译器会发出一个错误——不允许我们不正确实现的代码被成功编译。通常,如果以下任一条件不满足,则Java编译器将针对使用@Override注解的方法发出错误(引用自Override注解文档):

  • 该方法确实会覆盖或实现在超类中声明的方法。

  • 该方法的签名与在Object中声明的任何公共方法(即equals或hashCode方法)的签名覆盖等价(override-equivalent)。

因此,我们也可以使用此注解来确保子类方法实际上也覆盖超类中的非最终具体方法或抽象方法:

public abstract class Foo {    public int doSomething() {        return 1;      }    public abstract int doSomethingElse();  }public class Bar extends Foo {    @Override      public int doSomething() {        return 10;      }    @Override      public int doSomethingElse() {        return 20;      }  }  Foo bar = new Bar();  System.out.println(bar.doSomething());         // 10System.out.println(bar.doSomethingElse());     // 20

@Override注解不仅不限于超类中的具体或抽象方法,而且还可用于确保接口的方法也被覆盖(从JDK 6开始):

public interface Foo {    public int doSomething();  }public class Bar implements Foo {    @Override      public int doSomething() {        return 10;      }  } Foo bar = new Bar();  System.out.println(bar.doSomething());    // 10

通常,覆盖非final类方法、抽象超类方法或接口方法的任何方法都可以使用@Override进行注解。有关有效覆盖的更多信息,请参阅《Overriding and Hiding》文档 以及《Java Language Specification (JLS)》的第9.6.4.4章节。

@FunctionalInterface

随着JDK 8中lambda表达式的引入,函数式接口在Java中变得越来越流行。这些特殊类型的接口可以用lambda表达式、方法引用或构造函数引用代替。根据@FunctionalInterface文档,函数式接口的定义如下:

一个函数式接口只有一个抽象方法。由于默认方法有一个实现,所以它们不是抽象的。

例如,以下接口被视为函数式接口:

public interface Foo {    public int doSomething();  }public interface Bar {    public int doSomething();    public default int doSomethingElse() {        return 1;      }  }

因此,下面的每一个都可以用lambda表达式代替,如下所示:

public class FunctionalConsumer {    public void consumeFoo(Foo foo) {          System.out.println(foo.doSomething());      }    public void consumeBar(Bar bar) {          System.out.println(bar.doSomething());      }  }  FunctionalConsumer consumer = new FunctionalConsumer();  consumer.consumeFoo(() -> 10);    // 10consumer.consumeBar(() -> 20);    // 20

重点要注意的是,抽象类,即使它们只包含一个抽象方法,也不是函数式接口。更多信息,请参阅***Java语言架构师Brian Goetz编写的《Allow lambdas to implement abstract classes》。与@Override注解类似,Java编译器提供了@FunctionalInterface注解以确保接口确实是函数式接口。例如,我们可以将此注解添加到上面创建的接口中:

@FunctionalInterfacepublic interface Foo {    public int doSomething();  }@FunctionalInterfacepublic interface Bar {    public int doSomething();    public default int doSomethingElse() {        return 1;      }  }

如果我们错误地将接口定义为非函数接口并用@FunctionalInterface注解了错误的接口,则Java编译器会发出错误。例如,我们可以定义以下带注解的非函数式接口:

@FunctionalInterfacepublic interface Foo {    public int doSomething();    public int doSomethingElse();  }

如果我们试图编译这个接口,则会收到以下错误:

$ javac Foo.java  Foo.java:1: error: Unexpected @FunctionalInterface annotation  @FunctionalInterface  ^    Foo is not a functional interface      multiple non-overriding abstract methods found in interface Foo1 error

使用这个注解,我们可以确保我们不会错误地创建原本打算用作函数式接口的非函数式接口。需要注意的是,即使在@FunctionalInterface注解不存在的情况下,接口也可以用作函数式接口(可以替代为lambdas,方法引用和构造函数引用),正如我们前面的示例中所见的那样。这类似于@Override注解,即一个方法是可以被覆盖的,即使它不包含@Override注解。在这两种情况下,注解都是允许编译器执行期望意图的可选技术。

有关@FunctionalInterface注解的更多信息,请参阅@FunctionalInterface文档和《JLS》的第4.6.4.9章节。点击这里阅读 Java 10 新特性实战教程。

@SuppressWarnings

警告是所有编译器的重要组成部分,为开发人员提供的反馈——可能危险的行为或在未来的编译器版本中可能会出现的错误。例如,在Java中使用泛型类型而没有其关联的正式泛型参数(称为原始类型)会导致警告,就像使用不推荐使用的代码一样(请参阅下面的@Deprecated部分)。虽然这些警告很重要,但它们可能并不总是适用甚至并不总是正确的。例如,可能会有对不安全的类型转换发生警告的情况,但是基于使用它的上下文,我们可以保证它是安全的。

为了忽略某些上下文中的特定警告,JDK 5中引入了@SuppressWarnings注解。此注解接受一个或多个字符串参数——描述要忽略的警告名称。虽然这些警告的名称通常在编译器实现之间有所不同,但有3种警告在Java语言中是标准化的(因此在所有Java编译器实现中都很常见):

  • unchecked:表示类型转换未经检查的警告(编译器无法保证类型转换是安全的),导致发生的可能原因有访问原始类型的成员(参见《JLS》4.8章节)、窄参考转换或不安全的向下转换(参见《JLS》5.1.6章节)、未经检查的类型转换(参见《JLS》5.1.9章节)、使用带有可变参数的泛型参数(参见《JLS》8.4.1章节和下面的@SafeVarargs部分)、使用无效的协变返回类型(参见《JLS》8.4.8.3章节)、不确定的参数评估(参见《JLS》15.12.4.2章节),未经检查的方法引用类型的转换(参见《JLS》15.13.2章节)、或未经检查的lambda类型的对话(参见《JLS》15.27.3章节)。

  • deprecation:表示使用了已弃用的方法、类、类型等的警告(参见《JLS》9.6.4.6章节和下面的@Deprecated部分)。

  • removal:表示使用了最终废弃的方法、类、类型等的警告(参见《JLS》9.6.4.6章节和下面的@Deprecated部分)。

为了忽略特定的警告,可以将@SuppressedWarning注解与抑制警告(以字符串数组的形式提供)的一个或多个名字添加到发生警告的上下文中:

public class Foo {    public void doSomething(@SuppressWarnings("rawtypes") List myList) {        // Do something with myList      }  }

@SuppressWarnings注解可用于以下任何一种情况:

  • 类型

  • 方法

  • 参数

  • 构造函数

  • 局部变量

  • 模块

一般来说,@SuppressWarnings注解应该应用于最直接的警告范围。例如,如果方法中的局部变量应忽略警告,则应将@SuppressWarnings注解应用于局部变量,而不是包含局部变量的方法或类:

public class Foo {    public void doSomething() {        @SuppressWarnings("rawtypes")          List myList = new ArrayList();        // Do something with myList      }  }

@SafeVarargs

可变参数在Java中是一种很有用的技术手段,但在与泛型参数一起使用时,它们也可能会导致一些严重的问题。由于泛型在Java中是非特定的,所以具有泛型类型的变量的实际(实现)类型不能在运行时被断定。由于无法做出此判断,因此变量可能会存储非其实际类型的引用到类型,如以下代码片段所示(摘自《Java Generics FAQs》):

List ln = new ArrayList<Number>();  ln.add(1);  List<String> ls = ln;                 // unchecked warning String s = ls.get(0);                 // ClassCastException

在将ln分配给ls后,堆中存在变量ls,该变量具有List<String>的类型,但存储引用到实际为List<Number>类型的值。这个无效的引用被称为堆污染。由于直到运行时才能确定此错误,因此它会在编译时显示为警告,并在运行时出现ClassCastException。当泛型参数与可变参数组合时,可能会加剧此问题:

public class Foo {    public <T> void doSomething(T... args) {        // ...      }  }

在这种情况下,Java编译器会在调用站点内部创建一个数组来存储可变数量的参数,但是T的类型并未实现,因此在运行时会丢失。实质上,到doSomething的参数实际上是Object[]类型。如果依赖T的运行时类型,那么这会导致严重的问题,如下面的代码片段所示:

public class Foo {      public <T> void doSomething(T... args) {        Object[] objects = args;        String string = (String) objects[0];      }  }  Foo foo = new Foo();  foo.<Number>doSomething(1, 2);

如果执行此代码片段,那么将导致ClassCastException,因为在调用站点传递的***个Number参数不能转换为String(类似于独立堆污染示例中抛出的ClassCastException)。通常,可能会出现以下情况:编译器没有足够的信息来正确确定通用可变参数的确切类型,这会导致堆污染,这种污染可以通过允许内部可变参数数组从方法中转义来传播,如下面摘自《Effective Java》第3版 pp.147的例子:

public static <T> T[] toArray(T... args) {    return args;  }

在某些情况下,我们知道方法实际上是类型安全的,不会造成堆污染。如果可以在保证的情况下做出这个决定,那么我们可以使用@SafeVarargs注解来注解该方法,从而抑制与可能的堆污染相关的警告。但是,这引出了一个问题:什么时候通用可变参数方法会被认为是类型安全的?Josh Bloch在《Effective Java》第3版第147页的基础上提供了一个完善的解决方案&mdash;&mdash;基于方法与内部创建的用于存储其可变参数的数组的交互:

如果方法没有存储任何东西到数组(这会覆盖参数)且不允许对数组的引用进行转义(这会使得不受信任的代码可以访问数组),那么它是安全的。换句话说,如果可变参数数组仅用于从调用者向方法传递可变数量的参数&mdash;&mdash;毕竟,这是可变参数的目的&mdash;&mdash;那么该方法是安全的。

因此,如果我们创建了以下方法(来自pp.149同上),那么我们可以用@SafeVarags注解来合理地注解我们的方法:

@SafeVarargsstatic <T> List<T> flatten(List<? extends T>... lists) {    List<T> result = new ArrayList<>();    for (List<? extends T> list : lists) {          result.addAll(list);      }    return result;  }

有关@SafeVarargs注解的更多信息,请参阅@SafeVarargs文档,《JLS》9.6.4.7章节以及《Effective Java》第3版中的Item32。点击这里阅读 Java 10 新特性实战教程。

@Deprecated

在开发代码时,有时候代码会变得过时和不应该再被使用。在这些情况下,通常会有个替补的更适合手头的任务,且虽然现存的对过时代码的调用可能会保留,但是所有新的调用都应该使用替换方法。这个过时的代码被称为不推荐使用的代码。在某些紧急情况下,不建议使用的代码可能会被删除,应该在未来的框架或库版本从其代码库中删除弃用的代码之前立即转换为替换代码。

为了支持不推荐使用的代码的文档,Java包含@Deprecated注解,它会将一些构造函数、域、局部变量、方法、软件包、模块、参数或类型标记为已弃用。如果弃用的元素(构造函数,域,局部变量等)被使用了,则编译器发出警告。例如,我们可以创建一个弃用的类并按如下所示使用它:

@Deprecatedpublic class Foo {}  Foo foo = new Foo();

如果我们编译此代码(在命名为Main.java的文件中),我们会收到以下警告:

$ javac Main.javaNote: Main.java uses or overrides a deprecated api.Note: Recompile with -Xlint:deprecation for details.

通常,每当使用@Deprecated注解的元素时,都会引发警告,除了用于以下五种情况:

  • 声明本身就被声明为是弃用的(即递归调用)。

  • 声明被注解禁止弃用警告(即@SuppressWarnings(“deprecation”)注解,如上所述,应用于使用弃用元素的上下文。

  • 使用和声明都在同一个最外面的类中(即,如果类调用其本身的弃用方法)。

  • 用在import声明中,该声明导入通常不赞成使用的类型或构件(即,在将已弃用的类导入另一个类时)。

  • exports或opens指令内。

正如前面所说的,在某些情况下,当不推荐使用的元素将被删除,则调用代码应立即删除不推荐使用的元素(称为terminally deprecated code)。在这种情况下,可以使用forRemoval参数提供的@Deprecated注解,如下所示:

@Deprecated(forRemoval = true)public class Foo {}

使用此最终弃用代码会导致一系列更严格的警告:

$ javac Main.java  Main.java:7: warning: [removal] Foo in com.foo has been deprecated and marked for removal                  Foo foo = new Foo();                  ^  Main.java:7: warning: [removal] Foo in com.foo has been deprecated and marked for removal                  Foo foo = new Foo();                                ^2 warnings

除了标准@Deprcated注解所描述的相同异常之外,总是会发出最终弃用的警告。我们还可以通过为注解提供since变量来添加文档到@Deprecated注解中:

@Deprecated(since = "1.0.5", forRemoval = true)public class Foo {}

可以使用@deprecated JavaDoc元素(注意小写字母d)进一步文档化已弃用的元素,如以下代码片段所示:

@Deprecated(since = "1.0.5", forRemoval = true)public class Foo {}

JavaDoc工具将生成以下文档:

Java程序员必须掌握的注解有哪些

感谢各位的阅读,以上就是“Java程序员必须掌握的注解有哪些”的内容了,经过本文的学习后,相信大家对Java程序员必须掌握的注解有哪些这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: Java程序员必须掌握的注解有哪些

本文链接: https://lsjlt.com/news/286792.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java程序员必须掌握的注解有哪些
    这篇文章主要讲解了“Java程序员必须掌握的注解有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java程序员必须掌握的注解有哪些”吧!划重点自 JDK5 推出以来,注解已成为Java生...
    99+
    2023-06-17
  • Java 程序员必须掌握的 LeetCode 题目有哪些?
    作为一个 Java 程序员,掌握算法和数据结构是非常重要的。而 LeetCode 是一个非常好的平台,可以帮助我们练习算法和数据结构。在这篇文章中,我们将介绍 Java 程序员必须掌握的一些 LeetCode 题目,并且演示一下相应的代码...
    99+
    2023-08-21
    leetcode windows unix
  • Java程序员必需掌握的基础有哪些
    小编给大家分享一下Java程序员必需掌握的基础有哪些,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!1. 匿名类Java匿名类很像局部类或内联类,只是没有名字。我们可以利用匿名类,同时定义并实例化一个类。只有局部类...
    99+
    2023-06-16
  • Python 程序员必须掌握的分布式算法技能有哪些?
    随着互联网技术的不断发展,分布式系统已经成为了现代计算机系统的重要组成部分。在分布式系统中,为了保证系统的高效性和可靠性,需要使用一些专门的算法来进行处理。Python 作为一种高效的编程语言,也可以用于编写分布式系统的相关算法。在本文中...
    99+
    2023-09-16
    编程算法 分布式 linux
  • Java开发人员必须掌握哪些Linux命令?
    作为一名Java开发人员,无论是在开发、测试还是部署过程中,都需要经常与Linux系统打交道。因此,掌握一些基本的Linux命令是非常必要的。下面,本文将为大家介绍一些Java开发人员必须掌握的Linux命令。 ls命令 ls命令是L...
    99+
    2023-07-29
    linux leetcode windows
  • Java程序员必须掌握的Linux路径调试技巧?
    Java程序员必须掌握的Linux路径调试技巧 作为一名Java程序员,你是否曾经遇到过在Linux环境下运行Java程序时,出现了一些路径问题?可能你的应用程序无法找到某个文件或者资源文件,或者在Linux环境下出现了一些奇怪的问题。在这...
    99+
    2023-10-11
    linux path javascript
  • Java程序员需掌握的基础有哪些
    这篇文章主要介绍了Java程序员需掌握的基础有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1匿名类Java匿名类很像局部类或内联类,只是没有名字。我们可以利用匿名类,同...
    99+
    2023-06-02
  • java架构师必须掌握的技术有哪些
    这篇文章主要介绍“java架构师必须掌握的技术有哪些”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“java架构师必须掌握的技术有哪些”文章能帮助大家解决问题。一、前言一个成熟的大型网站(如淘宝、京东...
    99+
    2023-06-05
  • 程序员需要掌握SpringBoot中的哪些注解
    这篇文章给大家分享的是有关程序员需要掌握SpringBoot中的哪些注解的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言Spring经历了如下几个阶段:第一阶段:xml配置在Spring 1.x时代,...
    99+
    2023-06-02
  • PHP 开发人员必须掌握的索引技术有哪些?
    随着 Web 应用程序的不断发展,数据库也变得越来越重要。在处理大量数据时,数据索引技术可以大大提高数据库的性能和响应速度。在 PHP 开发中,掌握索引技术是非常重要的,这可以帮助 PHP 开发人员更高效地处理数据。本文将介绍 PHP 开...
    99+
    2023-08-19
    面试 索引 开发技术
  • ASP 程序员必须掌握的 http shell 对象知识。
    ASP 程序员必须掌握的 http shell 对象知识 在 ASP 开发中,http shell 对象是一个非常重要的对象,它可以让 ASP 程序员通过代码来操作系统的命令行,实现一些高级功能。这篇文章将介绍 ASP 程序员必须掌握的 h...
    99+
    2023-06-02
    http shell 对象
  • ASP 程序员必须掌握的 Windows 异步编程技巧?
    作为一名 ASP 程序员,掌握 Windows 异步编程技巧是非常重要的。异步编程可以提高程序的性能和响应速度,同时也可以让程序更加稳定可靠。在本文中,我们将介绍 ASP 程序员必须掌握的一些 Windows 异步编程技巧,并且结合实例演示...
    99+
    2023-10-02
    windows 面试 异步编程
  • PHP程序员必须掌握的编程算法是什么?
    编程算法是计算机科学中的重要部分,它们能够帮助程序员解决一系列的问题。对于PHP程序员来说,掌握一些基本的编程算法是非常必要的,因为这些算法可以帮助他们更有效地解决问题,提高编程效率。接下来,我们将介绍一些PHP程序员必须掌握的编程算法。...
    99+
    2023-08-12
    编程算法 spring 并发
  • Java 程序员掌握 Spring Boot非常有必要
    Spring Boot从天而降 Spring Boot是企业级开发的整体整合解决方案,在现在企业项目开发中使用非常普遍,Spring Boot 2.0 的推出又激起了一阵学习 Spr...
    99+
    2024-04-02
  • Java程序员必须了解哪些Linux发行版?
    Linux作为一个自由开源的操作系统,拥有着众多的发行版。对于Java程序员来说,学习和了解一些常用的Linux发行版是非常有必要的,因为在实际工作中,我们常常需要在Linux平台上进行Java开发。本文将介绍几个常用的Linux发行版,...
    99+
    2023-07-29
    linux leetcode windows
  • Java程序员必须清楚的性能指标有哪些
    本篇内容介绍了“Java程序员必须清楚的性能指标有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.响应时间和吞吐量根据应用程序的响应时...
    99+
    2023-06-16
  • Go编程新手必须掌握的算法有哪些?
    作为一门快速、高效的编程语言,Go 在近年来的发展中越来越受到开发者的欢迎。然而,对于 Go 编程新手而言,想要掌握这门语言,必须掌握一些基础算法。在本文中,我们将介绍 Go 编程新手必须掌握的算法。 一、排序算法 排序算法是计算机科学中最...
    99+
    2023-08-08
    编程算法 数据类型 开发技术
  • Java程序员所需要掌握的技能有哪些
    这篇文章跟大家分析一下“Java程序员所需要掌握的技能有哪些”。内容详细易懂,对“Java程序员所需要掌握的技能有哪些”感兴趣的朋友可以跟着小编的思路慢慢深入来阅读一下,希望阅读后能够对大家有所帮助。下面跟着小编一起深入学习“Java程序员...
    99+
    2023-06-02
  • SEOer必须掌握的标配技术有哪些
    这篇文章主要为大家展示了“SEOer必须掌握的标配技术有哪些”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“SEOer必须掌握的标配技术有哪些”这篇文章吧。  首先,认识网页代码是基础  这里所讲...
    99+
    2023-06-10
  • Java程序员必须掌握的Linux技能:如何在Linux上运行Java代码?
    Linux作为一个开源操作系统,已经成为了企业级应用开发的首选平台。而Java作为跨平台的编程语言,也越来越受到企业级应用开发人员的青睐。因此,Java程序员必须掌握在Linux上运行Java代码的技能。本文将介绍如何在Linux上运行J...
    99+
    2023-11-13
    linux leetcode 数组
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作