在方法中声明类 - 最终关键字 [英] Declaring class inside a method - Final keyword

查看:144
本文介绍了在方法中声明类 - 最终关键字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在方法中给出以下内部类(IsSomething):

Given the following inner class (IsSomething) within a method:

public class InnerMethod {

private int x;


public class Something {
    private int y;

    public void printMyNumber(double x)
    {
        class IsSomething extends Something {

            public void print() {
                System.out.println(x);
            }

        }
    }
}

}

为什么X变量必须是FINAL才能使它工作..?
(我说的是关于printMyNumber函数的X参数。)

Why does the X variable has to be FINAL to make it work..? (I'm talking ofc about the X parameter of the "printMyNumber" function.)

推荐答案

区别在于局部变量与类成员变量之间的关系。成员变量在封闭对象的生命周期中存在,因此它可以由内部类实例引用。但是,局部变量仅在方法调用期间存在,并且由编译器以不同方式处理,因为它的隐式副本是作为内部类的成员生成的。在没有声明局部变量fi​​nal的情况下,可以更改它,导致细微的错误,因为内部类仍然引用该变量的原始值。

The difference is between local variables vs class member variables. A member variable exists during the lifetime of the enclosing object, so it can be referenced by the inner class instance. A local variable, however, exists only during the method invocation, and is handled differently by the compiler, in that an implicit copy of it is generated as the member of the inner class. Without declaring the local variable final, one could change it, leading to subtle errors due to the inner class still referring to the original value of that variable.

最终本地变量


我知道创建局部变量或
参数final的原因有两个。第一个原因是您不希望代码
更改局部变量或参数。许多人认为
是改变方法内部参数的坏方式,因为它使
代码不清楚。作为一种习惯,一些程序员将所有参数都设为
final以防止自己更改它们。我不这样做,
因为我发现它让我的方法签名有点难看。

There are two reasons I know for making a local variable or a parameter final. The first reason is that you don't want your code changing the local variable or parameter. It is considered by many to be bad style to change a parameter inside a method as it makes the code unclear. As a habit, some programmers make all their parameters "final" to prevent themselves from changing them. I don't do that, since I find it makes my method signature a bit ugly.

当我们想要访问本地时,第二个原因出现了内部类中的变量或
参数。这是实际的原因,正如我所知,
,最终的局部变量和参数是在JDK 1.1中引入Java语言的

The second reason comes in when we want to access a local variable or parameter from within an inner class. This is the actual reason, as far as I know, that final local variables and parameters were introduced into the Java language in JDK 1.1.



public class Access1 {
  public void f() {
    final int i = 3;
    Runnable runnable = new Runnable() {
    public void run() {
      System.out.println(i);
    }
    };
  }
}

在run()方法中我们只能访问i如果我们把它放在外层的最后。要理解推理,我们必须

Inside the run() method we can only access i if we make it final in the outer class. To understand the reasoning, we have to


查看编译器的作用。它生成两个文件,Access1.class
和Access1 $ 1.class。当我们使用JAD对它们进行反编译时,我们得到:

look at what the compiler does. It produces two files, Access1.class and Access1$1.class. When we decompile them with JAD, we get:



public class Access1 {
  public Access1() {}
  public void f() {
    Access1$1 access1$1 = new Access1$1(this);
  }
}

class Access1$1 implements Runnable {
  Access1$1(Access1 access1) {
    this$0 = access1;
  }
  public void run() {
    System.out.println(3);
  }
  private final Access1 this$0;
}

由于i的值是final,编译器可以内联到内部

Since the value of i is final, the compiler can "inline" it into the inner


类。令我感到不安的是,局部变量必须是内部类访问的
,直到我看到上面的内容。

class. It perturbed me that the local variables had to be final to be accessed by the inner class until I saw the above.

当局部变量的值可以为内部类的不同
实例进行更改,编译器将其作为内部类的
的数据成员添加,并允许它在构造函数中初始化。这背后的
背后的原因是Java没有指针,即C的
方式。

When the value of the local variable can change for different instances of the inner class, the compiler adds it as a data member of the inner class and lets it be initialised in the constructor. The underlying reason behind this is that Java does not have pointers, the way that C has.

考虑以下类:



public class Access2 {
  public void f() {
    for (int i=0; i<10; i++) {
    final int value = i;
    Runnable runnable = new Runnable() {
      public void run() {
        System.out.println(value);
      }
    };
    }
  }
} 

这里的问题是我们每次我们进行for循环时都必须创建一个新的本地数据成员,所以我今天想到了

The problem here is that we have to make a new local data member each time we go through the for loop, so a thought I had today


编码时,是将上面的代码更改为以下内容:

while coding, was to change the above code to the following:



public class Access3 {
  public void f() {
    Runnable[] runners = new Runnable[10];
    for (final int[] i={0}; i[0]<runners.length; i[0]++) {
    runners[i[0]] = new Runnable() {
      private int counter = i[0];
      public void run() {
        System.out.println(counter);
      }
    };
    }
    for (int i=0; i<runners.length; i++)
    runners[i].run();
  }
  public static void main(String[] args) {
    new Access3().f();
  }
}

我们现在不需要申报额外的决赛局部变量。事实上,是不是真的

We now don't have to declare an additional final local variable. In fact, is it not perhaps true that


int []我就像一个指向int的常见C指针?我花了4年时间到
看到这个,但我想听听你是否在其他地方听到过这个想法

int[] i is like a common C pointer to an int? It took me 4 years to see this, but I'd like to hear from you if you have heard this idea somewhere else.

这篇关于在方法中声明类 - 最终关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆