首页 > java中接口的一点问题

java中接口的一点问题

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关键字

【热门文章】
【热门文章】