小编pol*_*nts的帖子

Eclipse bug?仅使用默认情况打开null

我正在尝试enum,我发现以下编译并在Eclipse上运行正常(Build id:20090920-1017,不确定编译器版本):

public class SwitchingOnAnull {
    enum X { ,; }
    public static void main(String[] args) {
        X x = null;
        switch(x) {
            default: System.out.println("Hello world!");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在使用Eclipse编译和运行时,这将"Hello world!"正常打印和退出.

使用javac编译器,这NullPointerException将按预期抛出.

那么Eclipse Java编译器中是否存在错误?

java eclipse null enums switch-statement

31
推荐指数
1
解决办法
7537
查看次数

不同的行为可能会导致精度下降

在Java中,当你这样做

int b = 0;
b = b + 1.0;
Run Code Online (Sandbox Code Playgroud)

您可能会丢失精度错误.但是,如果你这样做,为什么呢?

int b = 0;
b += 1.0;
Run Code Online (Sandbox Code Playgroud)

没有任何错误?

java implicit-cast compound-assignment

30
推荐指数
1
解决办法
2620
查看次数

在Java中扩展Throwable

Java允许您创建一个全新的子类型Throwable,例如:

public class FlyingPig extends Throwable { ... }
Run Code Online (Sandbox Code Playgroud)

现在,很少,我可以这样做:

throw new FlyingPig("Oink!");
Run Code Online (Sandbox Code Playgroud)

当然还有其他地方:

try { ... } catch (FlyingPig porky) { ... }
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  • 这是一个坏主意吗?如果是这样,为什么?
    • 如果这是一个坏主意,可以做些什么来阻止这种子类型?
    • 由于它不可预防(据我所知),可能导致什么灾难?
  • 如果这不是一个坏主意,为什么不呢?
    • 你怎么能从事可以做出有用的事情extends Throwable

拟议方案#1

真的想做这样的事情的场景具有以下属性:

  • "事件" 最终发生.这是预料之中的.它绝对不是一个Error,而且它什么也没Exception发生.
    • 因为它是预期的,所以会有一个catch等待它.它不会"滑倒"过去.它不会"逃避"任何catch一般Exception和/或任何尝试Error.
  • "事件" 极少发生.
  • 当它发生时,通常会有一个深层堆栈跟踪.

所以也许我现在很清楚我想说的FlyingPig是:这是一个详尽的递归搜索的结果.

要搜索的对象存在:它只是在大海中找到它的问题,即搜索空间.搜索过程很长,因此相对昂贵的异常处理成本可以忽略不计.事实上,传统的控制流构造使用boolean isFound标志的替代方案可能更昂贵,因为必须在整个搜索过程中连续检查,最有可能在递归的每个级别.此检查将在99.99%的时间内失败,但绝对有必要传播终止条件.在某种程度上,虽然有效,但检查效率低下!

通过简单的 …

java exception-handling throwable

28
推荐指数
3
解决办法
1万
查看次数

使用注释确保方法返回的值不会被丢弃

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:记录每种方法抛出的所有异常).有一个注释可以强制客户端不要忽略某些方法的返回值,并且编译器在编译时以错误或警告的形式强制执行它,这似乎符合这个想法.


附录2:片段

以下是初步尝试,简洁地说明了我想要实现的目标:

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

public class UndiscardableTest { …
Run Code Online (Sandbox Code Playgroud)

java annotations api-design return-value

28
推荐指数
3
解决办法
8958
查看次数

名词,动词,形容词等单独的单词列表

通常单词列表是包含所有内容的1个文件,但是可以单独下载名词列表,动词列表,形容词列表等吗?

我特意需要英语.

grammar dictionary spell-checking

27
推荐指数
5
解决办法
3万
查看次数

关于平等的最佳做法:过载还是不过载?

请考虑以下代码段:

import java.util.*;
public class EqualsOverload {
    public static void main(String[] args) {
        class Thing {
            final int x;
            Thing(int x)          { this.x = x; }
            public int hashCode() { return x; }

            public boolean equals(Thing other) { return this.x == other.x; }
        }
        List<Thing> myThings = Arrays.asList(new Thing(42));
        System.out.println(myThings.contains(new Thing(42))); // prints "false"
    }
}
Run Code Online (Sandbox Code Playgroud)

注意contains返回false!!! 我们似乎失去了我们的东西!

这个bug,当然是事实,我们不小心过载,而不是,重写,Object.equals(Object).如果我们class Thing改为编写如下,contains则按true预期返回.

        class Thing {
            final …
Run Code Online (Sandbox Code Playgroud)

java overriding overloading equals

26
推荐指数
2
解决办法
1万
查看次数

替换不在范围内的所有字符(Java String)

如何替换不符合条件的字符串中的所有字符.我在使用NOT运算符时遇到了麻烦.

具体来说,我试图删除所有不是数字的字符,到目前为止我已经尝试过了:

String number = "703-463-9281";
String number2 = number.replaceAll("[0-9]!", ""); // produces: "703-463-9281" (no change)
String number3 = number.replaceAll("[0-9]", "");  // produces: "--" 
String number4 = number.replaceAll("![0-9]", ""); // produces: "703-463-9281" (no change)
String number6 = number.replaceAll("^[0-9]", ""); // produces: "03-463-9281"
Run Code Online (Sandbox Code Playgroud)

java regex character-class

26
推荐指数
2
解决办法
3万
查看次数

是否保证Java中的新Integer(i)== i?

请考虑以下代码段:

    int i = 99999999;
    byte b = 99;
    short s = 9999;
    Integer ii = Integer.valueOf(9); // should be within cache

    System.out.println(new Integer(i) == i); // "true"
    System.out.println(new Integer(b) == b); // "true"
    System.out.println(new Integer(s) == s); // "true"
    System.out.println(new Integer(ii) == ii); // "false"
Run Code Online (Sandbox Code Playgroud)

很明显为什么最后一行总是打印出来"false":我们正在使用==引用标识比较,而new对象永远不会==已经存在的对象.

问题是前三行:那些比较保证在原语上int,Integer自动取消装箱?是否存在基元将被自动装箱的情况,并且执行参考标识比较?(那就是全部false!)

java comparison autoboxing implicit-conversion

25
推荐指数
2
解决办法
3008
查看次数

什么是惯用的Hamcrest模式断言迭代的每个元素匹配给定的匹配器?

检查以下代码段:

    assertThat(
        Arrays.asList("1x", "2x", "3x", "4z"),
        not(hasItem(not(endsWith("x"))))
    );
Run Code Online (Sandbox Code Playgroud)

这断言列表没有不以"x"结尾的元素.当然,这是表示列表中所有元素都以"x"结尾的双重否定方式.

另请注意,该片段会引发:

java.lang.AssertionError: 
Expected: not a collection containing not a string ending with "x"
     got: <[1x, 2x, 3x, 4z]>
Run Code Online (Sandbox Code Playgroud)

这列出了整个列表,而不仅仅是不以"x"结尾的元素.

那么有一种惯用的方式:

  • 断言每个元素以"x"结尾(没有双重否定)
  • 在断言错误时,仅列出那些不以"x"结尾的元素

java idioms hamcrest

25
推荐指数
2
解决办法
7405
查看次数

正则表达式太慢了吗?现实生活中的例子,简单的非正则表达式替代方案更好

我看到这里的人发表评论,比如"正则表达式太慢了!",或者"你为什么要用正则表达式做一些简单的事情!" (然后提出10+行代替)等.

我还没有真正在工业环境中使用正则表达式,所以我很好奇是否有正则表达式显然太慢的应用程序,并且存在一个简单的非正则表达式替代方案,其表现更好(甚至可能渐近!)更好.

很明显,许多使用复杂字符串算法的高度专业化的字符串操作将轻松胜过正则表达式,但我所说的是存在简单解决方案且明显优于正则表达式的情况.

怎样才算是简单的是主观的,当然,但我认为一个合理的标准是,如果仅使用String,StringBuilder等等,那么它可能简单.


注意:我非常感谢证明以下内容的答案:

  1. 一个初学者级的正则表达式解决方案,解决非玩具现实生活中可怕的问题
  2. 简单的非正则表达式解决方案
  3. 专家级正则表达式重写,表现相当

java regex string algorithm performance

24
推荐指数
4
解决办法
2万
查看次数