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

为什么x没有在这里初始化?

冀阳文
2023-03-14

为什么x没有在下面初始化?

public class rough {
    public static void main(String[] args) {
        int x;
        boolean found = false;
        for (int i = 0; i < 10; i++) {
            if (Math.random() < 0.5) {
                found = true;
                x = 10;
                break;
            }

        }
        if (!found)
            x = -1;
        System.out.println(x);//x isn't initialized here
    }
}

平均而言,对于一半的迭代,for循环中的if将是true,从而初始化x。对于另一半,找到的保持false,因此外部if将初始化。因此,我不明白为什么编译器会感到恼火。

作为最终蒸馏(见下面的简化),考虑

public static void main(String[] args) {
        int x;
        boolean found = false;
        if (!found)
            x = -1;

        System.out.println(x);
    }

这也给出了一个错误,x不是init。

以前的简化

更令人惊讶的是,更改if(Math.random()

事实上,进一步调查后,将原来的for循环替换为

        for (int i=0;i<1;i++)
           x = 10;
 for (; !found; ) {
            x = 10;
            break;
        }

同样糟糕。只有for(;;){...中断;}

共有2个答案

景星华
2023-03-14

(把这个作为一个单独的答案写下来,因为我认为它会从评论中受益)。

这就是语言——律师的回答。

语言规范要求在使用变量之前对其进行初始化。

规则包括:

>

编译器不考虑此分析中表达式的值。请参见示例16.2。

第二条规则解释了为什么即使在对我们来说“显而易见”的情况下,编译器也不能使用这些知识。即使编译器编写人员愿意进行更深入的分析,遵守Java规范也会禁止它。

如果下一个问题是“但是为什么?”那么我不得不猜测,但是标准的目的是获得一致的行为。你不希望一个编译器接受另一个编译器拒绝的合法Java。

周伟泽
2023-03-14

编译器不能很容易地检测到导致x被初始化的所有分支,但是您可以通过将-1分配给x来很容易地修复这个问题(以及代码)

public static void main(String[] args) {
    int x = -1;
    for (int i = 0; i < 10; i++) {
        if (Math.random() < 0.5) {
            x = 10;
            break;
        }
    }
    System.out.println(x);
}

现在你不需要找到(所以我也删除了它)。

 类似资料:
  • 问题:给您两个非空链表,表示两个非负整数。数字按相反顺序存储,每个节点包含一个数字。将这两个数字相加,并将其作为链表返回。 您可以假设这两个数字不包含任何前导零,除了数字0本身。 下面是我在JAVA中对这个问题的解决方案: 然而,为什么代码必须是 ,而不仅仅是:“listNode l3=new ListNode(0);”我知道这是错误的。如果我使用此代码,我的答案将返回[]。我不明白为什么会这样?

  • 如果我有一个struct Foo和一个struct Bar: 如果我初始化一个条并打印正确得到的值: 但是现在如果我声明这样的构造函数: 我失去了Bar::foo的默认构造,程序输出了32764 0 5! 为什么我不得不像这样无声地初始化每个成员变量: 只要我声明一个构造函数?在这种情况下,为什么默认构造不起作用?

  • 问题内容: 在C ++中,可以在构造函数开始运行之前使用初始化列表来初始化类的字段。例如: 我很好奇为什么Java没有类似的功能。根据 Core Java:第1卷 : C ++使用这种特殊语法来调用字段构造函数。在Java中,因为对象没有子对象,而只有指向其他对象的指针,所以不需要它。 这是我的问题: “由于对象没有子对象”是什么意思?我不知道什么是子对象(我尝试查找它);它们是否意味着扩展超类的

  • 问题内容: 我有这个代码: 这会导致编译错误:可能尚未初始化,这很公平。 现在,我将代码更改为: 我得到同样的编译错误!我必须初始化为null: 那么,不初始化对象和初始化为null有什么区别?如果我声明一个没有初始化的对象,它是否为null? 谢谢 问题答案: 字段(成员变量)被初始化为(或初始化为默认的原始值,如果它们是原始的) 局部变量未初始化,您有责任设置初始值。

  • 我在网上找了很久。但没有类似的答案。请帮忙或试着给出一些想法。我刚刚开始学习CyclicBarrier,我想知道我是否误解了CyclicBarrier.Await(int timeout,TimeUnit unit)。线程0到3已经到达了花费2秒的障碍点。同时,最后一个线程在等待2秒后启动。1秒后,0到3个线程到达指定的超时,其中第4个线程仍然执行自己的代码。问题是:为什么CyclicBarrie

  • 我确实读过这篇文章:https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/ 设置一些上下文:这篇文章是关于容器中的僵尸问题的,它试图说服我们这是一个真正的问题。 总的来说,我有复杂的感觉。为什么这很重要?毕竟,即使是在conainer主机操作系统中的僵尸能够释放/杀死这个僵尸的情况下。我们知道容