interface - java中接口的一点问题
大家讲道理
大家讲道理 2017-04-17 16:22:35
[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的值,这是为什么呢?

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全部回复(5)
伊谢尔伦

你实现这个接口时其实创建了一个内部类,这个内部类是属于外部类的,而不是构造他的方法的,所以他没法访问构造他方法里的非终态变量。
简单的来说,你再 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 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 的实例初始化,我们可以有效地为一个匿名内部类创建一个构建器:

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号