【问题标题】:Method working inside curly brackets but not outside [duplicate]在大括号内但不在大括号外工作的方法[重复]
【发布时间】:2021-03-20 11:58:53
【问题描述】:

这可能是一个基本问题,但请帮助我。我正在为井字游戏编写代码。我想使用哈希图来记录每个盒子的状态。

public class tictactoe extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tictactoe);
    }
    boolean player = true;
    
    Map<Integer , Integer> hashMaps = new HashMap<>();

    {hashMaps.put(233, 333);}


    public void thismeth(View view) {
        ImageView ig = (ImageView) view;
        ig.getId();

        if(player){ig.setImageResource(R.drawable.cross);
        player = false;
        ig.setEnabled(false);}
        else{
            ig.setImageResource(R.drawable.zero1);
            player = true;

            ig.setEnabled(false);
        }

    }
}

上面的代码sn -p不会在hashmap中抛出任何错误

public class tictactoe extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tictactoe);
    }
    boolean player = true;

    Map<Integer , Integer> hashMaps = new HashMap<>();

    hashMaps.put(233, 333);


    public void thismeth(View view) {
        ImageView ig = (ImageView) view;
        ig.getId();

        if(player){ig.setImageResource(R.drawable.cross);
        player = false;
        ig.setEnabled(false);}
        else{
            ig.setImageResource(R.drawable.zero1);
            player = true;

            ig.setEnabled(false);
        }

    }
} 

虽然此代码将 put() 显示为无效方法。没有大括号它不起作用,但使用大括号它可以。有人可以解释一下为什么它可以与大括号一起使用吗?

【问题讨论】:

标签: java android


【解决方案1】:

您只能在第一个示例中声明或初始化类中的对象。如果你需要使用它,那么它应该在方法或初始化块中。

花括号表示初始化块。这将在每次实例化类的对象时运行。

{
    // initialize...
}

初始化块也可以是static。这将只为一个类运行一次。

static {
    // ....
}

【讨论】:

    【解决方案2】:

    解释很简单:因为 Java 语言规范是这么说的。

    具体来说,代码不能出现在类中。代码只能出现在其他东西中,例如方法、构造函数、初始化程序或字段初始化表达式,并且这些可以在类中。

    因此:

    class Example {
       System.out.println("Hello");
    }
    

    不编译(想法是:您希望该代码何时运行?不清楚,因此,该代码没有意义,无意义的代码最好根本不编译)。

    相比之下,这个:

    class Example {
        private static final boolean whatever = sayHello();
    
        public static boolean sayHello() {
            System.out.println("Hello");
            return false;
        }
    }
    

    编译正常,即使我们在这里有 2 个“代码”实例:sayHello 方法包含打招呼的代码,whatever 字段的 = 符号后面的表达式包含代码 @987654326 @。

    想一想:可以使用立即值声明字段。这些都是合法的字段声明:

    long x;
    long y = 10;
    long z = System.currentTimeMillis();
    

    然而最后一个肯定需要代码实际执行(编译器不能为你“预运行”它,当前时间当然不是一个常数)。您可以使用称为“初始化程序”的构造来获得更大的灵活性:有“加载类时运行的代码”之类的东西,以及“创建新实例时运行的代码”之类的东西.最后一个有点模糊;你会想:构造函数,它在创建实例时运行 - 这是真的,但类似:class Example { long z = System.currentTimeMillis(); } 没有(可见的)构造函数,但是当你编写 new Example() 时代码需要运行。因此,是的,还有实例初始化代码。

    编写初始化程序的语言语法(它允许您在类或实例初始化期间运行任意代码,编译器将在您使用代码初始化字段时需要运行的代码放置在同一位置)是:

    静态初始化器(在应用程序的任何地方第一次使用该类时运行):

    static { codeHere(); }
    

    实例初始化器:

    { codeHere(); }
    

    是的,只是大括号。这是一个可以粘贴在类中的元素,这意味着:这是一个实例初始化程序——在创建新实例时运行。

    这就是您在{} 中粘贴map.put 语句时创建的内容。具体来说,这些是您的 class tictactoe 构造的直接内容:

    • protected void onCreate(Bundle savedInstanceState) - 一种方法。这些都是可以接受的。

    • boolean player = true; - 一个新字段;可以接受。使用直接在生成的类/apk 文件中硬编码的常量值进行初始化。

    • Map&lt;Integer , Integer&gt; hashMaps = new HashMap&lt;&gt;(); - 一个新字段;可接受,用代码初始化,代码将被转换为实例初始化器。

    • {hashMaps.put(233, 333);} - 一个实例初始化器。它将与 hashMaps = new HashMap&lt;&gt;(); 一起添加到实例初始化程序中。

    • public void thismeth(View view) { - 一种新方法。

    所有可以接受的东西。而只是 hashMap.put(233, 333);,它是一个表达式语句,不起作用 - 语句不能进入类,只能进入方法、构造函数、实例初始化程序和静态初始化程序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-01
      • 2017-09-10
      • 1970-01-01
      • 2021-04-27
      • 1970-01-01
      • 2017-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多