第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么this()和super()必須是構(gòu)造函數(shù)中的第一個語句?

為什么this()和super()必須是構(gòu)造函數(shù)中的第一個語句?

qq_笑_17 2019-04-20 17:15:52
Java要求如果在構(gòu)造函數(shù)中調(diào)用this()或super(),它必須是第一個語句。為什么?例如:public class MyClass {     public MyClass(int x) {}}public class MySubClass extends MyClass {     public MySubClass(int a, int b) {         int c = a + b;         super(c);  // COMPILE ERROR     }}Sun編譯器說“調(diào)用super必須是構(gòu)造函數(shù)中的第一個語句”。Eclipse編譯器說“構(gòu)造函數(shù)調(diào)用必須是構(gòu)造函數(shù)中的第一個語句”。但是,您可以通過重新安排代碼來解決這個問題:public class MySubClass extends MyClass {     public MySubClass(int a, int b) {         super(a + b);  // OK     }}這是另一個例子:public class MyClass {     public MyClass(List list) {}}public class MySubClassA extends MyClass {     public MySubClassA(Object item) {         // Create a list that contains the item, and pass the list to super         List list = new ArrayList();         list.add(item);         super(list);  // COMPILE ERROR     }}public class MySubClassB extends MyClass {     public MySubClassB(Object item) {         // Create a list that contains the item, and pass the list to super         super(Arrays.asList(new Object[] { item }));  // OK     }}因此,它不會阻止您在調(diào)用super之前執(zhí)行邏輯。它只是阻止你執(zhí)行不能適合單個表達(dá)式的邏輯。調(diào)用有類似的規(guī)則this()。編譯器說“調(diào)用this必須是構(gòu)造函數(shù)中的第一個語句”。為什么編譯器有這些限制?你能給出一個代碼示例嗎,如果編譯器沒有這個限制,會發(fā)生什么不好的事情?
查看完整描述

17 回答

?
幕布斯6054654

TA貢獻(xiàn)1876條經(jīng)驗(yàn) 獲得超7個贊

1)檢查超級是第一個聲明是不足以防止這個問題。例如,你可以把“super(someMethodInSuper());” 在你的構(gòu)造函數(shù)中。這會嘗試在構(gòu)造超類之前訪問它,即使super是第一個語句。(2)編譯器似乎實(shí)現(xiàn)了一個不同的檢查,它本身就足以防止這個問題。消息是“在調(diào)用超類型構(gòu)造函數(shù)之前無法引用xxx”。因此,檢查super是第一個語句是沒有必要的。

查看完整回答
反對 回復(fù) 2019-05-15
?
浮云間

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超4個贊

我通過鏈接構(gòu)造函數(shù)和靜態(tài)方法找到了解決這個問題的方法。我想做的事情看起來像這樣:

public class Foo extends Baz {
  private final Bar myBar;

  public Foo(String arg1, String arg2) {
    // ...
    // ... Some other stuff needed to construct a 'Bar'...
    // ...
    final Bar b = new Bar(arg1, arg2);
    super(b.baz()):
    myBar = b;
  }}

所以基本上構(gòu)造一個基于構(gòu)造函數(shù)參數(shù)的對象,將對象存儲在一個成員中,并將該對象的方法結(jié)果傳遞給super的構(gòu)造函數(shù)。使成員最終也是相當(dāng)重要的,因?yàn)轭惖谋举|(zhì)是它是不可變的。請注意,實(shí)際上,構(gòu)建Bar實(shí)際上需要一些中間對象,因此在我的實(shí)際用例中它不能簡化為單行。

我最終讓它的工作方式如下:

public class Foo extends Baz {
  private final Bar myBar;

  private static Bar makeBar(String arg1,  String arg2) {
    // My more complicated setup routine to actually make 'Bar' goes here...
    return new Bar(arg1, arg2);
  }

  public Foo(String arg1, String arg2) {
    this(makeBar(arg1, arg2));
  }

  private Foo(Bar bar) {
    super(bar.baz());
    myBar = bar;
  }}

合法代碼,它完成了在調(diào)用超級構(gòu)造函數(shù)之前執(zhí)行多個語句的任務(wù)。


查看完整回答
反對 回復(fù) 2019-05-15
?
弒天下

TA貢獻(xiàn)1818條經(jīng)驗(yàn) 獲得超8個贊

因?yàn)镴LS這么說。是否可以以兼容的方式更改JLS以允許它?對。但是,它會使語言規(guī)范變得復(fù)雜,這已經(jīng)非常復(fù)雜了。它不是一個非常有用的東西,它有很多方法(用方法的結(jié)果調(diào)用另一個構(gòu)造函數(shù)this(fn())- 該方法在另一個構(gòu)造函數(shù)之前調(diào)用,因此也是超級構(gòu)造函數(shù))。因此,進(jìn)行改變的功率重量比是不利的。

編輯2018年3月:在消息記錄:建筑和驗(yàn)證甲骨文是在暗示這個限制被刪除(但不像C#,this將是絕對未分配的構(gòu)造函數(shù)鏈之前(DU))。

從歷史上看,this()或super()必須是構(gòu)造函數(shù)中的第一個。這種限制從未受到歡迎,并被認(rèn)為是武斷的。有許多微妙的原因,包括驗(yàn)證特殊參與,導(dǎo)致了這種限制。多年來,我們已經(jīng)在虛擬機(jī)層面解決了這些問題,以至于考慮解除這一限制變得切實(shí)可行,不僅僅是記錄,而是所有構(gòu)造函數(shù)。


查看完整回答
反對 回復(fù) 2019-05-15
?
慕萊塢森

TA貢獻(xiàn)1810條經(jīng)驗(yàn) 獲得超4個贊

我相當(dāng)肯定(那些熟悉Java規(guī)范的人)會阻止你(a)被允許使用部分構(gòu)造的對象,以及(b)強(qiáng)迫父類的構(gòu)造函數(shù)構(gòu)造為“新的” “對象。

一些“壞”的例子是:

class Thing{
    final int x;
    Thing(int x) { this.x = x; }}class Bad1 extends Thing{
    final int z;
    Bad1(int x, int y)
    {
        this.z = this.x + this.y; // WHOOPS! x hasn't been set yet
        super(x);
    }        }class Bad2 extends Thing{
    final int y;
    Bad2(int x, int y)
    {
        this.x = 33;
        this.y = y; 
        super(x); // WHOOPS! x is supposed to be final
    }        }


查看完整回答
反對 回復(fù) 2019-05-15
?
慕哥6287543

TA貢獻(xiàn)1831條經(jīng)驗(yàn) 獲得超10個贊

你問為什么,以及其他答案,imo,并沒有真正說出為什么可以調(diào)用你的超級構(gòu)造函數(shù),但只有它是第一行。原因是你并沒有真正調(diào)用構(gòu)造函數(shù)。在C ++中,等效語法是

MySubClass: MyClass {public:

 MySubClass(int a, int b): MyClass(a+b)
 {
 }};

當(dāng)您在開放式大括號之前看到自己的初始化子句時,您知道它是特殊的。它在任何其余構(gòu)造函數(shù)運(yùn)行之前運(yùn)行,實(shí)際上在任何成員變量初始化之前運(yùn)行。Java并沒有那么不同。在構(gòu)造函數(shù)真正啟動之前,有一種方法可以在初始化子類的任何成員之前運(yùn)行一些代碼(其他構(gòu)造函數(shù))。這種方式是將“調(diào)用”(例如super)放在第一行。(在某種程度上,在第一個開放式大括號之前,super或者this在第一個開放大括號之前,即使你在之后鍵入它,因?yàn)樗鼘⒃谀阃瓿伤袃?nèi)容之前執(zhí)行。)開放大括號之后的任何其他代碼(如int c = a + b;)使編譯器說“哦,好吧,沒有其他構(gòu)造函數(shù),我們可以初始化所有內(nèi)容?!?nbsp;所以它會運(yùn)行并初始化你的超類和你的成員以及諸如此類的東西,然后在開放式大括號之后開始執(zhí)行代碼。

如果,幾行之后,它遇到一些代碼說“哦,當(dāng)你構(gòu)建這個對象時,這里是我希望你傳遞給基類的構(gòu)造函數(shù)的參數(shù)”,這已經(jīng)太晚了,它沒有有道理。所以你得到一個編譯器錯誤。


查看完整回答
反對 回復(fù) 2019-05-15
?
尚方寶劍之說

TA貢獻(xiàn)1788條經(jīng)驗(yàn) 獲得超4個贊

因此,它不會阻止您在調(diào)用super之前執(zhí)行邏輯。它只是阻止你執(zhí)行不能適合單個表達(dá)式的邏輯。

實(shí)際上你可以用幾次嘗試來執(zhí)行邏輯,你只需要將你的代碼包裝在一個靜態(tài)函數(shù)中并在super語句中調(diào)用它。

使用你的例子:

public class MySubClassC extends MyClass {
    public MySubClassC(Object item) {
        // Create a list that contains the item, and pass the list to super
        super(createList(item));  // OK
    }

    private static List createList(item) {
        List list = new ArrayList();
        list.add(item);
        return list;
    }}


查看完整回答
反對 回復(fù) 2019-05-15
?
一只名叫tom的貓

TA貢獻(xiàn)1906條經(jīng)驗(yàn) 獲得超3個贊

我完全同意,限制太強(qiáng)了。使用靜態(tài)輔助方法(如Tom Hawtin - 搭建建議)或?qū)⑺小皃re-super()計(jì)算”推入?yún)?shù)中的單個表達(dá)式并不總是可行的,例如:

class Sup {
    public Sup(final int x_) { 
        //cheap constructor 
    }
    public Sup(final Sup sup_) { 
        //expensive copy constructor 
    }}class Sub extends Sup {
    private int x;
    public Sub(final Sub aSub) {
        /* for aSub with aSub.x == 0, 
         * the expensive copy constructor is unnecessary:
         */

         /* if (aSub.x == 0) { 
          *    super(0);
          * } else {
          *    super(aSub);
          * } 
          * above gives error since if-construct before super() is not allowed.
          */

        /* super((aSub.x == 0) ? 0 : aSub); 
         * above gives error since the ?-operator's type is Object
         */

        super(aSub); // much slower :(  

        // further initialization of aSub
    }}

正如Carson Myers建議的那樣,使用“尚未構(gòu)造的對象”例外會有所幫助,但在每個對象構(gòu)造期間檢查這個會減慢執(zhí)行速度。我傾向于使Java編譯器更好地區(qū)分(而不是隨后禁止if語句但允許參數(shù)中的?-operator),即使這會使語言規(guī)范復(fù)雜化。


查看完整回答
反對 回復(fù) 2019-05-15
?
哈士奇WWW

TA貢獻(xiàn)1799條經(jīng)驗(yàn) 獲得超6個贊

構(gòu)造函數(shù)按推導(dǎo)順序完成執(zhí)行是有道理的。因?yàn)槌惒恢廊魏巫宇?,所以它需要?zhí)行的任何初始化都與子類執(zhí)行的任何初始化分離,并且可能是先決條件。因此,它必須首先完成其執(zhí)行。

一個簡單的演示:

class A {
    A() {
        System.out.println("Inside A's constructor.");
    }}class B extends A {
    B() {
        System.out.println("Inside B's constructor.");
    }}class C extends B {
    C() {
        System.out.println("Inside C's constructor.");
    }}class CallingCons {
    public static void main(String args[]) {
        C c = new C();
    }}

該程序的輸出是:

Inside A's constructorInside B's constructorInside C's constructor


查看完整回答
反對 回復(fù) 2019-05-15
?
侃侃爾雅

TA貢獻(xiàn)1801條經(jīng)驗(yàn) 獲得超16個贊

在調(diào)用它的構(gòu)造函數(shù)之前,您可以使用匿名初始化程序塊初始化子項(xiàng)中的字段。這個例子將證明:

public class Test {
    public static void main(String[] args) {
        new Child();
    }}class Parent {
    public Parent() {
        System.out.println("In parent");
    }}class Child extends Parent {

    {
        System.out.println("In initializer");
    }

    public Child() {
        super();
        System.out.println("In child");
    }}

這將輸出:

在父級中 
初始化者
在子級中


查看完整回答
反對 回復(fù) 2019-05-15
?
泛舟湖上清波郎朗

TA貢獻(xiàn)1818條經(jīng)驗(yàn) 獲得超3個贊

我找到了一個woraround。

這不會編譯:

public class MySubClass extends MyClass {
    public MySubClass(int a, int b) {
        int c = a + b;
        super(c);  // COMPILE ERROR
        doSomething(c);
        doSomething2(a);
        doSomething3(b);
    }}

這有效:

public class MySubClass extends MyClass {
    public MySubClass(int a, int b) {
        this(a + b);
        doSomething2(a);
        doSomething3(b);
    }

    private MySubClass(int c) {
        super(c);
        doSomething(c);
    }}


查看完整回答
反對 回復(fù) 2019-05-15
?
千巷貓影

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超7個贊

那是因?yàn)槟愕臉?gòu)造函數(shù)依賴于其他構(gòu)造函數(shù)。對于構(gòu)造函數(shù)正常工作,其他構(gòu)造函數(shù)必須正常工作,這是依賴的。這就是為什么必須首先檢查依賴構(gòu)造函數(shù),這些構(gòu)造函數(shù)首先在構(gòu)造函數(shù)中由this()或super()調(diào)用。如果由this()或super()調(diào)用的其他構(gòu)造函數(shù)有問題,那么什么點(diǎn)執(zhí)行其他語句,因?yàn)槿绻徽{(diào)用的構(gòu)造函數(shù)失敗,則所有構(gòu)造函數(shù)都會失敗。


查看完整回答
反對 回復(fù) 2019-05-15
?
千萬里不及你

TA貢獻(xiàn)1784條經(jīng)驗(yàn) 獲得超9個贊

實(shí)際上,super()是構(gòu)造函數(shù)的第一個語句,因?yàn)橐_保它的超類在構(gòu)造子類之前是完全形成的。即使super()你的第一個語句中沒有,編譯器也會為你添加它!


查看完整回答
反對 回復(fù) 2019-05-15
  • 17 回答
  • 0 關(guān)注
  • 1375 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號