public class Test {
interface Print{
void printNumber();
}
public static void work(Print print){
System.out.println("开始工作,现在打印一个数字");
print.printNumber();
System.out.println("结束工作。");
}
public static void main(String[] args){
int id = 5678;
work(new Print() {
@Override
public void printNumber() {
//id = 4444;
//假如我试图在这里更改id的值,就会报错,why?
System.out.println(id);
//没有报错是输出为5678
}
});
}
}
我把java学习中遇到的问题归结为以上测试类,如我上面的注释,当我重写接口中的方法时,在重写方法中无法修改id的值,这是为什么呢?
你实现这个接口时其实创建了一个内部类,这个内部类是属于外部类的,而不是构造他的方法的,所以他没法访问构造他方法里的非终态变量。
简单的来说,你再 people() 方法里建立实现 Print 接口的内部类,其中使用了 id 这个变量,而其实你是在 work() 方法里才调用了 Print ,其实这时候已经超出了 people() 的访问范围,你是没法访问到 id 这个变量的。不过Java提供里一个机制,你可以把 id 参数传入 Print 中,实际上这些参数会复制到 Print 中,不过为了确保产生歧义,这些参数都是终态的,你没法修改它(避免你以为修改它就能修改 people() 里的 id)。
局部内部类访问局部变量,局部变量应该被设置为final类型。
我搞错了。忽略我。。
若试图定义一个匿名内部类,并想使用在匿名内部类外部定义的一个对象,则编译器要求外部对象为final
属性。--来自 thinking in java 185页。
理解为:方法内部的匿名内部类 访问本方法的参数列表及方法内局部变量时,变量应为final。
补充一点,想修改id,可将id声明为 外部类 静态成员变量即可。
public class innerClass {
static int id = 5678;
interface Print{
void printNumber();
}
public static void work(Print print){
System.out.println("开始工作,现在打印一个数字");
print.printNumber();
System.out.println("结束工作。");
}
public static void main(String[] args){
work(new Print() {
@Override
public void printNumber() {
id = 4444;
System.out.println(id);
//没有报错是输出为4444
}
});
}
}
内部类 详见 编程思想 185页前后。
//: Parcel8.java
// An anonymous inner class that performs
// initialization. A briefer version
// of Parcel5.java.
package c07.innerscopes;
public class Parcel8 {
// Argument must be final to use inside
// anonymous inner class:
public Destination dest(final String dest) {
return new Destination() {
private String label = dest;
public String readLabel() { return label; }
};
}
public static void main(String[] args) {
Parcel8 p = new Parcel8();
Destination d = p.dest("Tanzania");
}
} ///:~
若试图定义一个匿名内部类,并想使用在匿名内部类外部定义的一个对象,则编译器要求外部对象为final
属性。这正是我们将dest()的自变量设为final 的原因。如果忘记这样做,就会得到一条编译期出错提示。
只要自己只是想分配一个字段,上述方法就肯定可行。但假如需要采取一些类似于构建器的行动,又应怎样
操作呢?通过Java 1.1 的实例初始化,我们可以有效地为一个匿名内部类创建一个构建器:
匿名内部类访问外部成类员变量时,成员变量前应该加final关键字