您的位置 首页 java

Java中,内部匿名类使用外部变量为什么要加final

开篇

小A :通过上篇文章,内部匿名类我明白了,可是我还有一个疑问,那就是内部匿名类引用外部变量为什么得加final呢?

MDove :好,那咱们今天就针对这个问题,好好的聊一聊。

内部匿名类引用外部变量为什么得加final

MDove :咱们改写一段简单的代码:

public class Main {
 public static void main(String[] args) {
 Main main = new Main();
 main.fun();
 }
 public void fun() {
 // 这里为什么赋值为null,因为避免String常量对效果的影响
 final String nameInner = null;
 lisenter = new FunLisenter() {
 @Override
 public void fun() {
 System.out.println(nameInner);
 }
 }.fun();
 }
}
 

MDove :首先,咱们先对这几行代码,先提一个问题:为什么内部匿名类能够访问到nameInner?一个方法,就是一个栈帧。对于 局部变量 来说,方法结束,栈帧弹出,局部变量烟消云散。那么为什么内部匿名类可以访问?

小A :对啊,为什么?

MDove :你来给我捧哏的?我问你问题呢?

小A :(小声哔哔)…我不知道啊。

MDove :让我们直接看 反编译 class文件

class Main$1 implements FunLisenter {
 Main$1(Main var1, String var2) {
 this.this$0 = var1;
 this.val$nameInner = var2;
 }
 public void fun() {
 System.out.println(this.val$nameInner);
 }
}
 

MDove :不用解释了吧?这个例子不光解释了内部匿名类为什么能够访问局部变量,还展示了持有外部引用的问题。局部变量nameInner,被我们的编译期在生成匿名内部类的时候以参数的形式赋值给了我们内部持有的外部变量了。因此我们调用fun()方法时,就直接使用this.val$nameInner。

小A :原来是这样…那为啥一定要加final呢?

MDove :其实这很好理解,首先问你一个问题。从java代码上来看局部变量nameInner和匿名内部类的nameInner是同一个对象么?

小A :那还用问么!当然是一个啦…

MDove :没错,从外部看,它的确是同一个。但是我们也反编译了字节码,发现这二者并非是同一个对象。咱们设想一下:如果我们不加final。在Java的这种设计下,一定会造成这种情况:我们在内部匿名类中重新赋值,但是局部变量并不会同步发生变化。因为按照这种设计,重新赋值,完全就是俩个变量!因此为了避免这种情况,索性加上了final。修改值不同步?连修改都不能修改,还需要什么同步!

其他语言的设计方案

小A :感觉是一个很别扭的设计?其他语言也是这样么?

MDove :你别说,其他语言还真不是这样。比如同为面向对象语言的C#:C#在编译过程中隐式的把变量包装在一个类里边。因此就可以避免修改不同步的问题。接下来我们用Java模拟一下这种方案:

public class Main {
 public static void main(String[] args) {
 Main main = new Main();
 main.fun();
 }
 public void fun() {
 final TempModel tempModel = new TempModel("Haha");
 System.out.println(tempModel.name);
 new FunLisenter() {
 @Override
 public void fun() {
 System.out.println(tempModel.name);
 tempModel.name = "Hehe";
 }
 }.fun();
 System.out.println(tempModel.name);
 }
}
public class TempMain {
 private String name;
 public TempMain(String name) {
 this.name = name;
 }
}
 

MDove :我们用简单的一个对象,包装了我们想使用的变量。这样就达到了,不用final的效果。

小A :TempModel也加final了呀?

MDove :加final那是因为Java语言的规定,你仔细想想,这是一个对象。加不加final会对内部的值造成影响么?这也就是C#实现局部变量的原理。

小A :好像还真是这么回事,看样子底层设计真的是一个很有艺术的学问。

剧终

文章来源:智云一二三科技

文章标题:Java中,内部匿名类使用外部变量为什么要加final

文章地址:https://www.zhihuclub.com/188817.shtml

关于作者: 智云科技

热门文章

评论已关闭

110条评论

  1. You actually reported this really well!
    write my dissertation hire dissertation writer

  2. You actually mentioned that well.
    new online casino games [url=https://bestonlinecasinoreal.us/]casino games online real money[/url] best online casino real money

  3. You actually reported this perfectly!
    how to write an about me page for a blog write my paper for me

  4. Thank you, Helpful stuff.
    [url=https://writinganessaycollegeservice.com/]essay writing service reviews[/url] essay writing service 3 hours [url=https://essayservicehelp.com/]cheap custom essay writing service[/url] college essay writing help

  5. Amazing material. With thanks!
    essay writing service law medical school personal statement

  6. Awesome information. With thanks.
    biology essay writing service help with college essay writing

  7. Whoa quite a lot of fantastic knowledge.
    paper writer services online paper writing service

  8. Cheers! A good amount of content!
    medical school personal statement how to write a college essay

  9. You have made your position quite well.!
    do my finance homework reddit do my homework

  10. You’ve made your point pretty clearly..
    is essay writing service legal essay paper writing service

  11. You actually suggested that really well.
    dissertation writer dissertation proposal
    write me an essay make an essay
    how to write a expository essay

  12. This is nicely put. !
    paper writing services legitimate best online essay writing service
    write my term paper parts of a research proposal
    free writing help

  13. Incredible a lot of useful information.
    thesis titles thesis paper
    write my essay for cheap persuasive essay writer
    writing 5 paragraph essay

  14. With thanks. A good amount of postings!
    pay for paper pay for essay papers
    dissertation writing services reviews phd dissertation help
    writing an explanatory essay

  15. Many thanks! I like it!
    help with my essay college application essay help
    urgent essay writing service essay writing sites
    essays services

  16. Nicely put. Thanks!
    do my homework for free do my math homework for me
    phd dissertation writing best dissertation
    customize writing

  17. Really loads of terrific advice.
    education essay writing service letter writing service
    pay to write essay order essay online
    writers wanted online

  18. Thanks a lot. Quite a lot of info!
    help with essay writing argumentative essay
    essay writer free trial essay writer
    write my essay review

  19. Thank you, Loads of tips!
    college paper writing service what is the best essay writing service
    thesis topic write a thesis
    does money buy happiness essay

  20. You made your point very well.!
    resume writing services student essay writing
    dissertation meaning custom dissertation writing services
    uc college essay

  21. Seriously lots of very good knowledge.
    research paper writing service best paper writing services
    dissertation editing services writing help
    write my essay canada

  22. Really tons of excellent info!
    do my college homework reddit do my homework
    dissertation def proquest dissertations
    copywriting service

  23. Terrific facts. Thanks!
    dissertation data analysis help dissertation writers
    professional essay writers write my paper
    custom resume writing

  24. Good forum posts, Appreciate it.
    need help writing an essay essay writing service
    good thesis statements thesis help
    writing assignment help

  25. Amazing knowledge. Appreciate it!
    pay for essay reviews pay for essays
    thesis paper write a thesis
    buying essay

网站地图