ChatGPT解决这个技术问题 Extra ChatGPT

Java 注释

Java中注解的目的是什么?我有一个模糊的想法,认为它们介于注释和实际代码之间。它们会在运行时影响程序吗?

它们的典型用途是什么?

它们是 Java 独有的吗?有 C++ 等价物吗?

你可以用注释做一些非常糟糕的事情。例如,如果您知道 Spring Framework 及其 @Transactional 注释,该注释在方法调用之前启动事务并在异常/错误时回滚并在成功事务时提交。它完全支持 SOC 原则(关注点分离)。很干净 ! Java规则! :-)
对我来说,这看起来像是 3 个问题。第二个本身就太宽泛了。
所有语法注释看起来都像接口。那么,编译器或 JVM 是如何知道其用途的呢?假设如果我们使用@Override -> 检查方法是否正确覆盖@Transactional,如上所述,它执行与事务相关的东西。对于所有这些注释,我们在哪里可以找到定义/逻辑?
没有注释之类的东西,因为所有注释没有共同的特征可以用来将它们放在一个抽象的概念组中,除了它们都以@符号开头。所以,你需要分别学习每一种注解(@Override、@interface、用户定义的注解),不要指望理解一种注解就能告诉你任何关于其他注解的信息。

M
Michael Hogenson

注释主要由检查其他代码的代码使用。它们通常用于在运行时修改(即装饰或包装)现有类以改变它们的行为。 JUnitHibernate 等框架使用注释来最大限度地减少您自己编写以使用框架所需的代码量。

Oracle 在其网站上有 a good explanation of the concept and its meaning in Java


这仅适用于用户定义的注释,这是一种特定类型的注释;例如,@Override 做了一些完全不同的事情。
A
Afshin Moazami

此外,它们是 Java 独有的吗,是否有 C++ 等价物?

不,但是 VB 和 C# 有 attributes ,它们是相同的。

它们的用途非常多样化。一个典型的 Java 示例,@Override 对代码没有影响,但如果修饰的方法实际上没有覆盖另一个方法,编译器可以使用它来生成警告(或错误)。类似地,方法可以被标记为过时的。

然后是反射。当您在代码中反映类的类型时,您可以访问属性并根据那里找到的信息采取行动。我不知道 Java 中的任何示例,但在 .NET 中,编译器使用它来生成类的 (de)serialization 信息、确定结构的 memory layout 和来自遗留库(以及其他)的 declare function imports。它们还控制 IDE 表单设计器的工作方式。

/EDIT:类的属性与标签接口类似(如 Java 中的 Serializable)。但是,.NET 编码指南说不要使用标签接口。此外,它们仅适用于类级别,而不适用于方法级别。


L
Lahiru Ashan

Anders 给出了很好的总结,这里是一个 JUnit 注解的例子

@Test(expected=IOException.class)
public void flatfileMissing() throws IOException {
    readFlatFile("testfiles"+separator+"flatfile_doesnotexist.dat");
}

这里的 @Test 注释告诉 JUnit flatfileMissing 方法是一个应该执行的测试,并且预期的结果是抛出的 IOException。因此,当您运行测试时,将调用此方法,测试将根据是否抛出 IOException 而通过或失败。


S
S.L. Barth

Java 还具有注释处理工具 (apt),您不仅可以在其中创建注释,还可以决定这些注释如何在源代码上工作。

Here 是介绍。


f
forsvarir

要查看您可以使用注释做的一些很酷的事情,请查看my JavaBean annotations and annotation processor

它们非常适合生成代码,在构建过程中添加额外的验证,而且我也一直在将它们用于错误消息框架(尚未发布 - 需要与老板沟通......)。


M
Machavity

通过字面定义,注释向元素添加注释。同样,Java 注释是我们插入到源代码中的标签,用于提供有关代码的更多信息。 Java 注释将信息与带注释的程序元素相关联。除了 Java 注释之外,Java 程序还有大量的非正式文档,这些文档通常包含在源代码文件的注释中。但是,Java 注释不同于注释,它们直接使用注释类型对程序元素进行注释,以描述注释的形式。 Java 注释以标准和结构化的方式呈现信息,以便处理工具可以轻松地使用它。


这只是用户定义的注释;像@Override 这样的内置函数没有做任何类似的事情。
C
Community

When do you use Java's @Override annotation and why? 该链接涉及一个关于何时应使用覆盖注释 (@override) 的问题。这可能有助于更好地理解注释的概念。请查看。


C
Chewpers

当涉及到 EJB 时,注释被称为选择隐式中间件方法而不是显式中间件方法,当您使用注释时,您正在从 API 中自定义您确切需要的内容,例如您需要为银行转账调用事务方法:不使用注释:代码将是

transfer(Account account1, Account account2, long amount)    
{
   // 1: Call middleware API to perform a security check
   // 2: Call middleware API to start a transaction
   // 3: Call middleware API to load rows from the database
   // 4: Subtract the balance from one account, add to the other
   // 5: Call middleware API to store rows in the database
   // 6: Call middleware API to end the transaction
}

使用 Annotation 时,您的代码不包含使用中间件服务的繁琐 API 调用。代码干净,专注于业务逻辑

transfer(Account account1, Account account2, long amount) 
{
   // 1: Subtract the balance from one account, add to the other
}

S
Sean

刚接触注解的人首先会问到注解是:“什么是注解?”事实证明,这个问题没有答案,因为在所有各种 java 注释中都没有共同的行为。换句话说,除了它们都以“@”符号开头这一事实之外,没有任何东西可以将它们绑定到一个抽象的概念组中。

例如,有@Override 注解,它告诉编译器检查这个成员函数是否覆盖了父类中的一个。有@Target 注释,用于指定用户定义的注释(与其他类型的注释没有共同之处的第三种构造)可以附加到哪些类型的对象。除了以 @ 符号开头之外,它们彼此没有任何关系。

基本上,似乎已经发生的事情是,一些负责维护 java 语言定义的委员会正在为 java 语言添加新关键字做把关,因此其他开发人员正在通过调用新关键字“注释”来结束这一点。这就是为什么通常很难理解注释是什么的原因:因为没有共同的特征可以链接所有可用于将它们放入概念组的注释。换句话说,注释作为一个概念是不存在的。

因此,我建议单独研究每种不同注释的行为,不要指望理解一种注释可以告诉你关于其他注释的任何信息。

这个问题的许多其他答案都假设用户专门询问用户定义的注释,这是一种定义一组整数或字符串或其他数据的注释,它们附加到的类或方法或变量是静态的,可以在编译时或运行时查询。可悲的是,没有任何标记可以将这种注释与其他类型的注释区分开来,例如 @interface 做不同的事情。