String
在Java中是不可变的.从广义上讲,以下片段是"错误的".
String s = "hello world!";
s.toUpperCase(); // "wrong"!!
System.out.println(s); // still "hello world!"!!!
Run Code Online (Sandbox Code Playgroud)
尽管这是"错误的",代码编译和运行,也许是许多初学者的困惑,他们必须被告知错误是什么,或者通过查阅文档找出自己.
阅读文档是理解API的重要部分,但我想知道是否可以通过额外的编译时检查来补充它.特别是,我想知道是否可以使用Java的注释框架来强制执行某些方法返回的值不被忽略.然后,API设计者/库作者将在其方法中使用此批注来记录不应忽略的返回值.
一旦API补充了这个注释(或者可能是另一种机制),那么每当用户编写如上所述的代码时,它就不会编译(或者通过严厉的警告进行编译).
那么这可以做到,你会怎么做这样的事情?
很明显,在一般情况下,Java 应该允许忽略方法的返回值.可以在大多数时间安全地忽略像List.add
(always true
),System.setProperty
(previous value)这样的方法的返回值.
然而,也有很多的方法,其返回值应不被忽略.这样做几乎总是程序员错误,或者不正确使用API.这包括以下内容:
String
,BigInteger
等)的方法,它返回操作结果而不是改变它被调用的实例.InputStream.read(byte[])
返回读取的字节数,这应该不被假定为阵列的整个长度)目前,我们可以编写忽略这些返回值的代码,并让它们在没有警告的情况下编译和运行.静态分析检查器/ bug查找器/样式执行器/等几乎可以肯定地将这些标记为可能的代码气味,但如果可以通过API本身(可能通过注释)强制执行,那么它似乎是合适的/理想的.
一个类几乎不可能确保它总是"正确"使用,但它可以做些什么来帮助指导客户正确使用(参见:Effective Java 2nd Edition,Item 58:对可恢复的条件使用已检查的异常和编程错误的运行时异常和项62:记录每种方法抛出的所有异常).有一个注释可以强制客户端不要忽略某些方法的返回值,并且编译器在编译时以错误或警告的形式强制执行它,这似乎符合这个想法.
以下是初步尝试,简洁地说明了我想要实现的目标:
@interface Undiscardable { }
//attachable to methods to indicate that its
//return value must not be discarded
public class UndiscardableTest { …
Run Code Online (Sandbox Code Playgroud)