当前位置: 首页 > 面试题库 >

默认变量的值与默认情况下的初始化

彭鸿文
2023-03-14
问题内容

众所周知,根据JLS7
p.4.12.5,
每个实例变量均使用默认值初始化。例如(1):

public class Test {
    private Integer a;  // == null
    private int b;      // == 0
    private boolean c;  // == false
}

但是我一直认为,这样的类实现(2):

public class Test {
    private Integer a = null;
    private int b = 0;
    private boolean c = false;
}

绝对等于示例(1)。我期望,复杂的Java编译器会看到(2)中的所有这些初始化值都是多余的,并忽略了它们。

但是突然对于这两个类,我们有两个不同的字节码。

例如(1):

   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

例如(2):

   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   aload_0
   5:   aconst_null
   6:   putfield    #2; //Field a:Ljava/lang/Integer;
   9:   aload_0
   10:  iconst_0
   11:  putfield    #3; //Field b:I
   14:  aload_0
   15:  iconst_0
   16:  putfield    #4; //Field c:Z
   19:  return

问题是: 为什么?但这是显而易见的要优化的事情。什么原因?

UPD: 我使用Java 7 1.7.0.11 x64,没有特殊的javac选项


问题答案:

不,它们不相等。默认值在对象实例化时 立即 分配。当调用超类构造函数时,将在字段初始化程序中进行赋值……这意味着在某些情况下您
发现有所不同。样例代码

class Superclass {
    public Superclass() {
        someMethod();
    }

    void someMethod() {}
}

class Subclass extends Superclass {
    private int explicit = 0;
    private int implicit;

    public Subclass() {
        System.out.println("explicit: " + explicit);
        System.out.println("implicit: " + implicit);
    }

    @Override void someMethod() {
        explicit = 5;
        implicit = 5;
    }
}

public class Test {
    public static void main(String[] args) {
        new Subclass();
    }
}

输出:

explicit: 0
implicit: 5

在这里,您可以看到explicitSuperclass构造函数完成之后但在子类构造函数 执行之前,显式字段初始化将值重置为0
。的价值implicit仍然具有多态调用中指定的值someMethodSuperclass构造。



 类似资料:
  • 考虑以下代码 VS2013编译器发出以下警告: 警告C4351:新行为:数组“B::member”的元素将默认初始化1 这里有记载 使用C 11,并应用“默认初始化”的概念,意味着B. part的元素将不会被初始化。 但我认为,成员{}应该执行值初始化,而不是默认初始化。VS2013编译器是否损坏? 8.5美元/6 默认初始化类型为T的对象意味着:-如果T是(可能是cv限定的)类类型(第9条),则

  • 我有以下验证组: 默认情况下,如果没有指定组,那么是否应该验证使用扩展的组注释的所有字段?

  • 默认情况下,我们的路由器是Yaf_Router, 而默认使用的路由协议是Yaf_Route_Static,是基于HTTP路由的, 它期望一个请求是HTTP请求并且请求对象是使用Yaf_Request_Http

  • 根据我的参考,基元类型具有默认值,对象为null。我测试了一段代码。 行将是指向变量的错误,表示,而在给定引用中,将作为默认值。但是,使用下面给定的代码,它将实际打印。 第一个代码可能会出什么问题?类变量的行为是否与局部变量不同?

  • 经过在internet上的搜索,我知道了在交互式/非交互式-登录/非登录shell组合的情况下应该在哪里更改PATH变量的值。 从另一个帖子中找到的 我有“/bin/sh”作为缺省登录shell,只有/etc/profile文件用于导出系统中所有需要的环境变量。在非交互式登录shell的情况下,/etc/profile也不会被引用,尽管上面的link说它会被引用。但当我执行时, 我可以看到PATH

  • 行动时刻 - 设置变量的默认值 我们并不总是确定变量是否存在。 Unlang为我们提供了语法,以便在变量不存在时指定默认值。 我们将再次通过修改上一个练习来证明这一点。 我们将使用radtest首先在请求中包含Framed-Protocol = PPP,并将其排除在外。 如果Framed-Protocol AVP不存在,我们将返回一个默认字符串。 编辑FreeRADIUS配置目录下的sites-a