`
491823151
  • 浏览: 4442 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

匿名类中的final

    博客分类:
  • Java
阅读更多

 

关于final大家都知道,网上一搜一大片,大体说的都是final的意思就是保证我们所定义的变量的值不可改变或者引用不可改变~~

总所周知,在java匿名类中我们要去使用外部的局部变量或者参数是,这个被匿名类使用的变量必须是final的,但是大家有没有想过为什么必须是final,总不能说他是final我们就写final好了,这做法白痴都会,接下来我们来讲解下其内部原因。

在介绍之前我们首先要讲解下java中的值传递和引用传递的问题,大家都知道java是值传递,例

 

public class Test {
	public static void main(String[] args) {
		String s ="out";
		test1(s);
		System.out.println(s);
	}
	
	public  static void test1(String s){
		s = "inner";
	}

}

 

 打印结果是:"out",这也就是java值传递导致的原因,简单分析下吧,在我们讲s变量传递到test1方法中去的时候,实际上是在栈上copy了一份s的引用,然后操作这个引用,当s重新赋值的时候地址就改变(String是不可变的嘛),完全没有影响到原先s的内容。

介绍了java值传递后,接下来我们来说回归正题,如下面这段代码:

 

//定义个抽象类
abstract class AbstractClass{
	
	public abstract void m();
}


public static void test(final String s){   
	AbstractClass c = new AbstractClass(){
	   public void m(){
	      s = "inner";
	      System.out.println(s);
	   }
        };
}

 

 实际上这段代码是被编译成:

 

 

  public static void test(final String s){
     class OuterClass$1 extends AbstractClass{

        private final String s;
        public OuterClass$1(String s){
            this.s = s;   
        }
        public void m(){
              s = "inner";
	      System.out.println(s);
        }
     };
      AbstractClassc = new OuterClass$1(s);
 }

 

 可以看到s对象是被传递到了构造函数当中,当我们在使用m来打印出来,但如果java可以让我们以非final类型的参数传递进去的话。由java值传递可知,我们在匿名类中修改该变量的值,那在外部是不可见的。

举个最常见的例子,大家都写过button,我们为他添加匿名类事件监听器,如果我们在内部里面修改了外部变量的引用,那我们在外面是获取不到修改了的值的,这个可以接受?这也就是上面我们所举的值传递的例子。

 

所以结论出来了,我们在匿名类中需要传递进来final关键字,java希望的是保证内部实现和外在表现的一致性。

 

ok。。写完了自己的一些看法。一些内容参考部分内容参见http://blog.csdn.net/axman/archive/2006/12/25/1460544.aspx

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics