我最近决定开始使用空校验和注释(@NotNull
),我使用Intellij Idea's annotations library来访问这些注释。我试图弄清楚这些注释是否会在运行时工作以检查值是否为null,如果是,它如何处理这些错误(例如它是否抛出NullPointerException
,它是否只返回默认值(例如null,0,false))。此外,如果这些注释不起作用,那么有一个不同的集合可能是更加标准化的注释,它们将在运行时工作(例如javax
)?如果这些不起作用,我应该停止使用它们并返回标准的空校验和(if(x == null)
),还是应该同时使用注释和标准的空校验和?虽然我在这里是@Nullable这样的注释是个好主意吗?
答案 0 :(得分:2)
是的,它会在运行时检查并在double *pp[2];
// Here gcc warns about "cast to pointer from integer of different size"
pp[0]=(double *)aligned_alloc(4096, 10*4096*sizeof(double) );
*(pp[0]+1) = 55.55; // This compiles but segfaults
// or
*pp[0][1] = 55.55; // This gives compilation error.
时抛出IllegalArgumentException
。
答案 1 :(得分:0)
如果这些注释不起作用,那么是否存在另一组可能是更标准化的注释,它们将在运行时起作用(例如javax)?如果这些方法不起作用,我应该停止使用它们并返回标准的空校验和(
if(x == null)
),还是应该同时使用注释和标准的空校验和?
依赖注释进行运行时行为的问题在于,程序的正确性取决于所执行的注释处理的预期形式。例如,对于null检查,您需要一个注释处理器(可能集成到您的编译器中)以在编译时或编译前识别特定的注释,并采取您想要的操作:插入null检查代码。
尽管某些注释会在运行时保留,但您不会直接从中获得运行时行为。而是,可以通过反射性地分析您的类的代码来检查和执行这些注释及其属性。基本上,从注释的运行时保留中什么都不会得到,只有从主动寻找它们的代码中什么都没有。
如果需要运行时null检查,则应插入显式检查。如果您愿意依靠注释和相关的静态分析来确保不需要进行空检查,那么这就是您的要求。您应牢记的注意事项包括:
关于公共方法及其参数或公共字段的注释不能可靠地静态地防止第三方向您的代码提供空值,因为它们不需要使用执行适当的静态分析的工具来构建其代码
注释也不能防止将空值反射或通过本机代码馈入您的方法,因为这两种方法都绕过了编译器和所有关联的静态分析。
人们往往在NullPointerException
中赚得太大。由IllegalArgumentException
(例如)而不是NullPointerException
通知滥用行为几乎没有客观优势(如果有的话)。 NPE更具体地描述问题的性质,而IAE更具体地描述问题的背景。重要的是要确保及早发现问题。
当我在这里时,像@Nullable这样的注释是个好主意吗?
它们向您的代码添加了外部依赖关系,这是应该考虑的成本。他们专门以机器可操作的方式表达您的期望,这是相应的好处。如果您正在使用的注释库对希望向其分发源的每个人都可以使用,并且如果具有运行时保留的那些注释对希望对您的代码进行运行的每个人都可以使用,则注释可能是纯收益。否则,他们将是初学者。