(java) java中接口的一点问题

public class Test { interface Print{ void printNumber; } public static void workPrint print{ System.out.println"开始工作,现在打印一个数字"; print.printNumber; System.out.println"结束工作。"; } public static void mainString[] args{ int id = 5678; worknew Print { @Override public void printNumber { //id = 4444; //假如我试图在这里更改id的值,就会报错,why? System.out.printlnid; //没有报错是输出为5678 } }; } }

我把java学习中遇到的问题归结为以上测试类,如我上面的注释,当我重写接口中的方法时,在重写方法中无法修改id的值,这是为什么呢?

你实现这个接口时其实创建了一个内部类,这个内部类是属于外部类的,而不是构造他的方法的,所以他没法访问构造他方法里的非终态变量。
简单的来说,你再 people 方法里建立实现 Print 接口的内部类,其中使用了 id 这个变量,而其实你是在 work 方法里才调用了 Print ,其实这时候已经超出了 people 的访问范围,你是没法访问到 id 这个变量的。不过Java提供里一个机制,你可以把 id 参数传入 Print 中,实际上这些参数会复制到 Print 中,不过为了确保产生歧义,这些参数都是终态的,你没法修改它(避免你以为修改它就能修改 people 里的 id)。

我搞错了。忽略我。。

局部内部类访问局部变量,局部变量应该被设置为final类型。

匿名内部类访问外部成类员变量时,成员变量前应该加final关键字

若试图定义一个匿名内部类,并想使用在匿名内部类外部定义的一个对象,则编译器要求外部对象为final
属性。–来自 thinking in java 185页。

理解为:方法内部的匿名内部类 访问本方法的参数列表及方法内局部变量时,变量应为final。

补充一点,想修改id,可将id声明为 外部类 静态成员变量即可。
public class innerClass {

static int id = 5678; interface Print{ void printNumber;
} public static void workPrint print{ System.out.println"开始工作,现在打印一个数字"; print.printNumber; System.out.println"结束工作。";
} public static void mainString[] args{ worknew Print { @Override public void printNumber { id = 4444; System.out.printlnid; //没有报错是输出为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 destfinal String dest {
return new Destination {
private String label = dest;
public String readLabel { return label; }
};
}
public static void mainString[] args {
Parcel8 p = new Parcel8;
Destination d = p.dest"Tanzania";
}
} ///:~

若试图定义一个匿名内部类,并想使用在匿名内部类外部定义的一个对象,则编译器要求外部对象为final
属性。这正是我们将dest的自变量设为final 的原因。如果忘记这样做,就会得到一条编译期出错提示。
只要自己只是想分配一个字段,上述方法就肯定可行。但假如需要采取一些类似于构建器的行动,又应怎样
操作呢?通过Java 1.1 的实例初始化,我们可以有效地为一个匿名内部类创建一个构建器:

发表评论

电子邮件地址不会被公开。 必填项已用*标注