当前位置: 首页 > 知识库问答 >
问题:

Java SafeVarargs注释,是否存在标准或最佳实践?

孟鹤龄
2023-03-14

我最近遇到了java@safevarargs注释。谷歌搜索是什么使Java中的可变函数变得不安全,这让我相当困惑(堆中毒?删除类型?),所以我想知道一些事情:

>

  • @safevarargs意义上,是什么使一个不同的Java函数不安全(最好以深入示例的形式解释)?

    是否有一些标准必须遵守,以确保他的功能确实是安全的?如果没有,有什么最佳做法来确保它?

  • 共有1个答案

    赫连冠玉
    2023-03-14

    1)在Internet和StackOverflow上有很多关于泛型和varargs的特殊问题的例子。基本上,当你有一个可变数量的类型参数类型时:

    <T> void foo(T... args);
    

    在Java中,varargs是在编译时进行简单“重写”的语法糖:x...类型的varargs参数被转换为x[]类型的参数;每次调用这个varargs方法时,编译器都会收集varargs参数中的所有“变量参数”,并创建一个类似于new x[]{...(arguments go here)...}的数组。

    当varargs类型是具体的,比如string...时,这种方法可以很好地工作。当它是像t..这样的类型变量时,当t是该调用的具体类型时,它也可以工作。例如,如果上面的方法是类foo 的一部分,并且您有foo 引用,那么对它调用foo,因为我们知道t代码中的string

    但是,当t的“value”是另一个类型参数时,它就不起作用了。在Java中,不可能创建类型参数组件类型的数组(new t[]{...})。因此,Java转而使用new object[]{...}(这里objectt的上限;如果有不同的上限,那么它将代替object),然后给您一个编译器警告。

    那么,创建新对象[]而不是新t[]或其他什么有什么问题呢?Java中的数组在运行时知道它们的组件类型。因此,传递的数组对象将在运行时具有错误的组件类型。

    对于varargs最常见的用法,简单地迭代元素,这是没有问题的(您不关心数组的运行时类型),所以这是安全的:

    @SafeVarargs
    final <T> void foo(T... args) {
        for (T x : args) {
            // do stuff with x
        }
    }
    

    但是,对于依赖于传递数组的运行时组件类型的任何内容,都将不安全。下面是一个不安全和崩溃的简单示例:

    class UnSafeVarargs
    {
      static <T> T[] asArray(T... args) {
        return args;
      }
    
      static <T> T[] arrayOfTwo(T a, T b) {
        return asArray(a, b);
      }
    
      public static void main(String[] args) {
        String[] bar = arrayOfTwo("hi", "mom");
      }
    }
    

    这里的问题是,我们依赖于args的类型为t[],以便将其返回为t[]。但实际上,运行时参数的类型不是t[]的实例。

      null

    2)我上面提到的区分太复杂了,很难自动区分。

     类似资料:
    • 问题内容: 我最近遇到了Java 批注。搜寻是什么使Java中的可变参数功能不安全,这让我感到很困惑(堆中毒?擦除了类型?),所以我想知道一些事情: 是什么使得可变参数Java函数在某种意义上不安全(最好以深入示例的形式进行解释)? 为什么该注释留给程序员自己决定?这不是编译器应该能够检查的东西吗? 为了确保其功能确实是安全的,是否必须遵循一些标准?如果没有,有什么最佳实践来确保呢? 问题答案:

    • 问题内容: 在python中,您通常使用PEP 8-Python代码样式指南 作为您的编码标准/准则吗?您还有其他更喜欢的正式标准吗? 问题答案: “在python中,您通常使用PEP 8-Python代码样式指南作为您的编码标准/准则吗?您是否还需要其他正式的标准?” 如您所提到的,请遵循PEP 8作为主要文本,并遵循PEP 257 作为文档字符串约定 与Python样式指南一起,建议您参考以下

    • 我最近开始阅读注释。我在这里弃用了armStrong()方法,我需要抑制弃用警告,但无论我放在哪里,它都会显示“不必要的@SuppressWarnings(“弃用”)”。 有没有人能告诉我应该把它放在哪里,这样方法就不推荐了,警告就不会再出现了?

    • 我观看了本Spring开机教程:https://javabrains.io/courses/spring_bootquickstart/lessons/Creating-a-Spring-Data-JPA-Repository 它将@Entity注释放在类名之前。当我试图在我的代码中这样做时,我得到一个错误,说“无法解析@Entity”。 这是我的pom.xml文件: 你知道有什么问题吗?

    • 问题内容: 我想知道是否存在某种“标准”用于在数据库中存储美国地址?看来这是一项常见的任务,应该有某种标准。 我正在寻找的是数据库表应如何工作和交互的 特定 模式,已经是第三种标准形式,包括数据类型(MySQL)。一个好的UML文档将起作用。 也许我只是在偷懒,但这是一个非常常见的任务,而且我确信有人发布了在某处进行此操作的有效方法。我只是不知道在哪里寻找,而Google并没有帮助。请指出我的资源

    • 问题内容: 我们有很多对象,我们希望为其实现简单的输出对象属性的对象。其中一些属性可能是复杂的对象本身。 是否有任何标准,或者仅仅是样式的最佳实践?我在想类似的东西: 在这种情况下,嵌套值将如下所示: 我们正在使用Java,但是我发现自己在大多数语言中都在问同样的问题! 问题答案: 就我个人而言,我发现混合使用它并不太容易立即获得层次结构的视图。 我喜欢这种格式(并且已经在很多地方看到它使用过):