簡體   English   中英

改匿名class為static

[英]Change anonymous class to static

以下代碼向我顯示以下錯誤:

“片段應該是 static 這樣它們可以被系統重新實例化,匿名類不是靜態的”

我該如何解決?

private void showGameOverDialog(final int messageId) {
        // DialogFragment to display game stats and start new game
        final DialogFragment gameResult =
                new DialogFragment() { //**error in this place**
                    // create an AlertDialog and return it
                    @Override
                    public Dialog onCreateDialog(Bundle bundle) {
                        // create dialog displaying String resource for messageId
                        AlertDialog.Builder builder =
                                new AlertDialog.Builder(getActivity());
                        builder.setTitle(getResources().getString(messageId));

                        // display number of shots fired and total time elapsed
                        builder.setMessage(getResources().getString(
                                R.string.results_format, shotsFired, totalElapsedTime));
                        builder.setPositiveButton(R.string.reset_game,
                                new DialogInterface.OnClickListener() {
                                    // called when "Reset Game" Button is pressed

                                    @Override
                                    public void onClick(DialogInterface dialog,
                                                        int which) {
                                        dialogIsDisplayed = false;
                                        newGame(); // set up and start a new game
                                    }
                                }
                        );

                        return builder.create(); // return the AlertDialog
                    }
                };

        // in GUI thread, use FragmentManager to display the DialogFragment
        activity.runOnUiThread(
                new Runnable() {
                    public void run() {
                        showSystemBars();
                        dialogIsDisplayed = true;
                        gameResult.setCancelable(false); // modal dialog
                        gameResult.show(activity.getFragmentManager(), "results");
                    }
                }
        );
    }

new SomeType(args) { <-- 這是一個“匿名類”聲明,以及該錯誤所抱怨的內容。 那是因為這樣的代碼是簡寫的。

假設您有:

class Example {
   void foo() {
     new Object() {
       void foo() {}
     };
   }
}

那么這只是以下內容的簡寫:

class Example {
   void foo() {
     class MyObject$1 {
       void foo() {}
     }

     new MyObject$1();
   }
}

換句話說,您定義的 class 完全相同,只是 - 使用不相關的名稱,因為您只會在該行實例化它。 但是你仍然在定義一個 class。

所有在 class 內且未標記為 [A] 'local'(在方法聲明內)或 [B]且未標記為static的類都有點神奇:它們有一個您看不到的外部類型的秘密字段. 這是因為此類內部類的實例被認為存在於外部(包含)class 實例的上下文中,並且該上下文存儲在該隱藏字段中。 這就是為什么您可以從內部 class 內部的外部 class 調用實例方法,以及與字段交互的原因。 但是你在哪個實例中調用它? 好吧,在那個“神奇”的無形領域。

這一切都相當復雜,並且它使從凍結狀態恢復變得困難,因此發出警告。

簡單的解決方案是永遠不要有這樣的類,其中包含魔法領域。 要做到這一點:

  • 始終將您在類中編寫的任何類標記為static
  • 永遠不要在任何方法中聲明任何 class。
  • 永遠不要使用new X() {語法。

這些是......相當繁重的限制。 您仍然可以使用 lambda 語法編寫“函數”,但我不確定 android 是否支持它(android 或多或少在時間上被凍結,過去 10 多年左右,在 lambda 語法存在於 java 語言之前)。 但這就是錯誤告訴你你不能做的。

你必須做類似的事情:

class TheClassThatCodeYouPastedIsIn {
  private static class MyClickListener implements DialogInterface.OnClickListener {
    // called when "Reset Game" Button is pressed

    private final TheClassThatCodeYouPastedIsIn instance;
    MyClickListener(TheClassThatCodeYouPastedIsIn instance) {
      this.instance = instance;
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
      dialogIsDisplayed = false;
      instance.newGame(); // set up and start a new game
    }
  }

  private void showGameOverDialog(final int messageId) {
    // ... rest of the code.

    builder.setPositiveButton(R.string.reset_game, new MyClickListener(this));
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM