本文介绍了使用注释,以确保方法返回值不丢弃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

字符串在Java中是不可变的。下面的代码片断是,从广义上说,错误的。

String in Java is immutable. The following snippet is, broadly speaking, "wrong".

String s = "hello world!";

s.toUpperCase(); // "wrong"!!

System.out.println(s); // still "hello world!"!!!

尽管这是错误的,在code编译和运行,也许是很多初学者,谁必须要么被告知这个错误是什么,或查阅资料,找出自己的困惑。

Despite this being "wrong", the code compiles and runs, perhaps to the confusion of many beginners, who must either be told what the mistake is, or to find out for themselves by consulting the documentation.

阅读该文档是了解一个API的重要组成部分,但我不知道这是否可以通过附加的编译时检查加以补充。我特别想知道,如果可能的Java的注解框架可以用来强制执行某些方法的返回值不忽略。 API设计者/库作者随后将使用此批注在他们的方法来记录其返回值不应该被忽视。

Reading the documentation is an essential part of understanding an API, but I'm wondering if this can be supplemented by additional compile-time checks. In particular, I'm wondering if perhaps Java's annotation framework can be used to enforce that the value returned by certain methods are not ignored. API designers/library authors would then use this annotation in their methods to document which return values should not be ignored.

一旦API补充了此注释(或者其他机制),那么当用户写了一个code,如上述,它不会编译(或用严厉的警告这样做)。

Once the API is supplemented with this annotation (or perhaps another mechanism), then whenever a user writes a code such as above, it would not compile (or do so with a stern warning).

所以,可以这样做,你将如何去做这样的事情?

So can this be done, and how would you go about doing something like this?

这似乎很清楚,在一般情况下,爪哇的的允许的方法的返回值被忽略。像<$c$c>List.add总是真正),<$c$c>System.setProperty (previous值),大概可以安全地忽略大部分的时间。

It seems clear that in the general case, Java should allow return values of methods to be ignored. The returned values of methods like List.add (always true), System.setProperty (previous value), can probably be safely ignored most of the times.

不过,也有很多方法的返回值应的的被忽略。这样做几乎总是一个程序员的错误,否则没有API的正确用法。这些包括喜欢的东西:

However, there are also many methods whose return values should NOT be ignored. Doing so is almost always a programmer error, or otherwise not a proper usage of the API. These includes things like:


    上返回的结果字符串,的BigInteger 等)
  • 方法EM>操作,而不是变异它被调用的实例。

  • 方法的返回值是其行为的重要组成部分,不应该被忽视,但人们有时会做呢(如<$c$c>InputStream.read(byte[])返回读取的字节数,应该不是的被假定为在阵列的整个长度)

  • Methods on immutable types (e.g. String, BigInteger, etc) that return the result of operations instead of mutating the instance it is invoked on.
  • Methods whose return value is a critical part of its behavior and should not be ignored, but people sometimes do anyway (e.g. InputStream.read(byte[]) returns the number of bytes read, which should NOT be assumed to be the entire length of the array)

目前,我们可以C $ CS忽略这些返回值,并让它们编译并没有警告运行写$。静态分析跳棋/错误的发现者/风格执法者的/ etc几乎可以肯定标记这些尽可能code气味,但它似乎这是否可以通过API本身强制执行,或者通过注释是适当/理想的。

Currently we can write codes that ignores these return values and have them compile and run without warning. Static analysis checkers/bug finders/style enforcers/etc can almost certainly flag these as possible code smells, but it would seem to be appropriate/ideal if this can be enforced by the API itself, perhaps through annotations.

这几乎是不可能的一类,以确保其始终用正常,但有些事情可以做,以帮助指导客户正确使用(参见:有效的Java第二版,编号58:使用检查恢复情况和运行时异常的编程错误异常的和的项目62:文档每种方法引发的所有异常的)。有了这样会强制客户不能忽视某些方法的返回值的注释,并让它在编译时,编译器执行任何错误或警告的形式,似乎是与这种想法一致。

It is almost impossible for a class to ensure that it is always used "properly", but there are things it can do to help guide clients to proper usage (see: Effective Java 2nd Edition, Item 58: Use checked exceptions for recoverable conditions and runtime exceptions for programming errors and Item 62: Document all exceptions thrown by each method). Having an annotation that would enforce clients to not ignore return values of certain methods, and having it enforced by the compiler at compile-time either in the form of errors or warnings, would seem to be in line with this idea.

以下是preliminary尝试,简要地说明我想达到什么:

The following is a preliminary attempt that succinctly illustrates what I want to achieve:

@interface Undiscardable { }
//attachable to methods to indicate that its
//return value must not be discarded

public class UndiscardableTest {
     public static @Undiscardable int f() {
             return 42;
     }

     public static void main(String[] args) {
             f(); // what do I have to do so this generates
                  // compilation warning/error?

             System.out.println(f()); // this one would be fine!
     }
}

以上code编译并运行良好()。我怎样才能使它不是如此呢?我如何分配我想要的语义 @Undiscardable

The above code compiles and runs fine (as seen on ideone.com). How can I make it not so? How can I assign the semantics I want to @Undiscardable?

推荐答案

我不知道是否可行的 - 尤其是在一个可移植的方式 - 但看看的的。他用annotation处理 Sun公司的javac 私有API来访问源$ C ​​$ C做增加了罗马数字的文字到Java的一些替代

I'm not sure of the feasibility - especially in a portable way - but have a look at Roman Numerals, in our Java from Adrian Kuhn. He used annotation processing AND Sun's javac private API to adds Roman numeral literals to Java by visiting the source code to do some replacement.

也许你可以使用类似的方法为:

Maybe you could use a similar approach to:


  • 找到在源$ C ​​$ C
  • 您的注释方法调用
  • 检查结果分配(不容易IMO)

    • 生成一个编译器警告,如果不是

    • find calls to your annotated method in the source code
    • check if the result is assigned (won't be easy IMO)
      • generate a compiler warning if not

      和不从艾德里安的帖子错过以下资源:

      And don't miss the following resources from Adrian's post:

      您可能还喜欢


          
      • 通过大卫二妮

      •   
      • ,链接集合

      •   

      •   
      • Hacker’s Guide to the Java Compiler by David Erni
      • Javac Hacker Resources, a collection of links
      • How to rewrite assertions such that they cannot be turned off!


      Reference

      • Roman Numerals, in our Java




        • Plugging in to Java compilers
        • How to intentionally cause a custom java compiler warning message?
        • How to create a custom Annotation and processing it using APT?

        这篇关于使用注释,以确保方法返回值不丢弃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 10:04
查看更多