Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 1是一个神奇的数字吗?反模式?代码气味?当局的引文和指南_Java_Magic Numbers - Fatal编程技术网

Java 1是一个神奇的数字吗?反模式?代码气味?当局的引文和指南

Java 1是一个神奇的数字吗?反模式?代码气味?当局的引文和指南,java,magic-numbers,Java,Magic Numbers,可能重复: 我在各种API中看到了-1,最常见的是在搜索具有零基索引的“集合”时,通常表示“未找到”索引。这“有效”,因为-1从来都不是一个合法的索引。似乎任何负数都应该起作用,但我认为几乎总是使用-1,作为某种(不成文的)惯例 我想将范围限制在Java,至少现在是这样。我的问题是: Sun关于使用-1作为这样的“特殊”返回值的官方说法是什么 关于这个问题,有哪些引用,例如James Gosling、Josh Bloch,甚至Java以外的其他权威人士 过去关于这个问题有哪些值得注意的讨论

可能重复:

我在各种API中看到了
-1
,最常见的是在搜索具有零基索引的“集合”时,通常表示“未找到”索引。这“有效”,因为
-1
从来都不是一个合法的索引。似乎任何负数都应该起作用,但我认为几乎总是使用
-1
,作为某种(不成文的)惯例

我想将范围限制在Java,至少现在是这样。我的问题是:

  • Sun关于使用
    -1
    作为这样的“特殊”返回值的官方说法是什么
  • 关于这个问题,有哪些引用,例如James Gosling、Josh Bloch,甚至Java以外的其他权威人士
  • 过去关于这个问题有哪些值得注意的讨论

  • 当找不到索引时,Java和JavaScript都使用
    -1
    。由于索引总是
    0-n
    ,因此这似乎是一个非常明显的选择

    //JavaScript
    var url = 'example.com/foo?bar&admin=true';
    if(url.indexOf('&admin') != -1){
      alert('we likely have an insecure app!');
    }
    
    我发现这种方法(我在扩展数组类型元素时使用了
    .indexOf()
    方法)非常正常


    另一方面,您可以尝试使用PHP方法,例如,但由于存在多个返回类型(未找到时返回FALSE),这会让人感到困惑。

    最好为代码中的所有常量值定义一个最终的类变量。
    但一般接受使用0,1,-1“(空字符串),而不使用显式声明。

    这是从C继承的,其中只能返回单个原语值。在java中,还可以返回单个对象

    因此,对于新代码,返回一个basetype对象,其子类型指示instaceof要使用的问题,或者抛出一个“not Found”异常


    对于现有的特殊值,相应地在您的代码名中使-1成为常量-未找到-因此读者无需检查javadocs即可说出其含义

    null
    相同的做法适用于
    -1
    。它被讨论了很多次


    e、 g.

    之所以使用它,是因为它是在基于0的数组中遇到的第一个无效值。正如您所知,并非所有类型都可以包含null或nothing,因此需要“something”来表示nothing


    我想说它不是官方的,它只是成为了惯例(不成文),因为它非常适合这种情况。就我个人而言,我不认为这是一个问题。API设计也取决于作者,但是。

    在类型不包括范围检查的语言中,这是一个常见的习惯用法。“越界”值用于指示多个条件之一。这里,返回值表示两件事:1)字符是在哪里找到的,2)在哪里找到的。 使用-1表示
    未找到
    ,使用非负索引表示
    已找到
    可将这两个值简洁地编码为一个值,
    未找到
    这一事实不需要返回索引

    在具有严格范围检查的语言中,如Ada或Pascal,该方法可以实现为(伪代码)

    Positive
    是int的一个子类型,但仅限于非负值

    这将发现/未发现标志与位置分开。该位置作为输出参数提供-本质上是另一个返回值。它也可以是一个in-out参数,用于从给定位置开始搜索。此处不允许使用-1表示找不到,因为它违反了正数类型的范围检查

    java中的备选方案有:

    • 抛出异常:这不是一个好的选择,因为找不到角色不是一个异常情况
    • 将结果拆分为几种方法,例如
      boolean indexOf(char c);int lastFoundIndex()。这意味着对象必须保持状态,而状态在并发程序中不起作用,除非状态存储在线程本地存储中,或者使用同步——所有这些都会带来相当大的开销
    • 分别返回位置和查找标志:例如
      布尔索引of(char c,position pos)
      。这里,创建位置对象可能被视为不必要的开销
    • 创建多值返回类型
    比如

    class FindIndex {
       boolean found;
       int position;
    }
    
    FindIndex indexOf(char c);
    
    尽管它清楚地分隔了返回值,但它会承受对象创建开销。通过将
    FindIndex
    作为参数传递,可以缓解其中的一些问题,例如:

    FindIndex indexOf(char c, FindIndex start);
    
    顺便说一句,多个返回值将成为java(oak)的一部分,但在1.0之前就被删除了,以缩短发布时间。詹姆斯·戈斯林,他希望他们也包括在内。这仍然是一个问题

    我的观点是,使用魔术值是在单个返回值中编码多值结果(一个标志和一个值)的一种实用方法,而不需要过多的对象创建开销

    但是,如果使用魔法值,如果它们在相关api调用中保持一致,那么使用魔法值会更好。比如说,

       // get everything after the first c
       int index = str.indexOf('c');
       String afterC = str.substring(index);
    

    Java在这方面存在不足,因为在调用
    子字符串
    时使用-1将导致
    IndeOutOfBoundsException
    。相反,如果将负值视为从字符串末尾开始,则使用-1调用substring时返回“”可能更一致。错误条件下神奇值的批评者说返回值可以忽略(或假定为正)。以有用的方式处理这些神奇值的一致api将减少检查-1的需要,并允许更干净的代码。

    据我所知,这些值称为sentinel值,尽管大多数常见的定义与此场景略有不同

    Java等语言选择不支持按引用传递(我认为这是一个好主意),因此,虽然各个参数的值是可变的,但传递给函数的变量不受影响。因此,y
       // get everything after the first c
       int index = str.indexOf('c');
       String afterC = str.substring(index);
    
    someCollection.objectAtIndex(someCollection.indexOf(someObject)) == someObject
    
    int i = someString.indexOf("substring");
    if (i>=0) {
      // do stuff with found index
    } else {
      // handle not found case
    }