从一开始,说出事java匿名内部类
java内部类、匿名类原本以为它们的使用已经很滑, 成绩, 就在昨天晚上12指向时钟发生重大事故。事故的严重程度再说吧,那是因为我没有睡一晚睡眠。
那以下先用一段模拟代码来描写叙述下我出现的问题的:
public class Test {
public static void main(String[] args) throws InterruptedException {
View v = new View();
v.show(1);
Thread.sleep(500);
v.mTextView.execute();
Thread.sleep(1000);
v.show(2);
Thread.sleep(500);
v.mTextView.execute();
}
} class View {
public TextView mTextView; public void show(int position) {
if(mTextView == null) {
mTextView = new TextView();
mTextView.setListener(new Listener() {
@Override
public void click() {
System.out.println("position = " + position);
}
});
} mTextView.show();
}
} class TextView {
private Listener mListener; public void setListener(Listener l) {
mListener = l;
} public void execute() {
mListener.click();
} public void show() {
System.out.println("textview show...");
}
} interface Listener {
public void click();
}
不出意外的话。 console肯定是打印的1 2。 可是偏偏就在这困扰到我了。打印的结果是1 1, 细致顺一下代码,我们就应该去思考这个匿名内部类究竟是怎么使用的外部类那个方法的參数的。
从打印的结果上看, 我猜想肯定是在这个内部类的实例中保存了position參数。那带着这个猜想。我们来debug一下程序。
这是第一次运行到的时候, 发现什么问题了吗。
在mListener中居然有一个和position相关的变量。到这里,我们感觉那个推測可能是正确的。再往下思考,既然在mListener对象中保存了这个变量,那么下次运行到,同一个对象。所以变量肯定是同样的,这样也就解开我们的疑惑了。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcWliaW4wNTA2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
总结一下:
在我们new一个匿名内部类的时候,假设使用了方法中的东西,那么jvm会给我们的匿名类加一个构造方法,而且将这个參数传递进来,比如上面的样例中:
class View$Listener {
public View$Listener(int position) {
this.Listener$position = position;
} public void click() {
...
}
}
既然知道了这些。那么我们的疑惑也就解开了, 那上面的问题怎么解决呢? 事实上我们非常早之前就已经知道解决方法了,想想android中自己定义Adapter的getView()方法。你会恍然大悟。上面的问题怎么解决呢?就是把setListener放到if后面,而不是里面。
public class Test {
public static void main(String[] args) throws InterruptedException {
View v = new View();
v.show(1);
Thread.sleep(500);
v.mTextView.execute();
Thread.sleep(1000);
v.show(2);
Thread.sleep(500);
v.mTextView.execute();
}
} class View {
public TextView mTextView; public void show(int position) {
if(mTextView == null) {
mTextView = new TextView();
// mTextView.setListener(new Listener() {
// @Override
// public void click() {
// System.out.println("position = " + position);
// }
// });
} mTextView.setListener(new Listener() {
@Override
public void click() {
System.out.println("position = " + position);
}
}); mTextView.show();
}
} class TextView {
private Listener mListener; public void setListener(Listener l) {
mListener = l;
} public void execute() {
mListener.click();
} public void show() {
System.out.println("textview show...");
}
} interface Listener {
public void click();
}
这样在每次调用show方法时,都会又一次new一个Listener内部类。
版权声明:本文来源于Loader's Blog。博客,未经同意不得转载。
从一开始,说出事java匿名内部类的更多相关文章
- #随笔之java匿名内部类
随笔之java匿名内部类 从今天起开始每日一篇技术博客,当然这只是我当天所学的一些随笔,里面或多或少会有理解不当的地方,希望大家多多指教,一起进步! 在讲匿名内部类之前,先讲讲内部类的一些概念. 1. ...
- (转)java匿名内部类详解
原文:http://android.blog.51cto.com/268543/384844/ 内部类是指在一个外部类的内部再定义一个类.类名不需要和文件夹相同. *内部类可以是静态static的 ...
- 【Java学习笔记之二十六】深入理解Java匿名内部类
在[Java学习笔记之二十五]初步认知Java内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意 ...
- 【50】java 匿名内部类剖析
匿名内部类介绍: 匿名内部类也就是没有名字的内部类 正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写 但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口 匿名内部类的声明 ...
- JAVA匿名内部类(Anonymous Classes)
1.前言 匿名内部类在我们JAVA程序员的日常工作中经常要用到,但是很多时候也只是照本宣科地用,虽然也在用,但往往忽略了以下几点:为什么能这么用?匿名内部类的语法是怎样的?有哪些限制?因此,最近,我在 ...
- Java匿名内部类访问外部
匿名内部类访问外部局部变量必须是final修饰的,Java 1.8 会默认为其加上final 例子如下: public void send(String topicName, T obj) { Str ...
- 为什么Java匿名内部类访问的外部局部变量或参数需要被final修饰
大部分时候,类被定义成一个独立的程序单元.在某些情况下,也会把一个类放在另一个类的内部定义,这个定义在其他类内部的类就被称为内部类,包含内部类的类也被称为外部类. class Outer { priv ...
- Java 匿名内部类 & 内部类
一.JAVA中内部类和匿名内部类的区别 内部类:内部类可以是static的或者非static的,static内部类只能包含静态方法和静态类变量,只能访问外部类的静态元素,内部类可以实例化,多次使用. ...
- java匿名内部类使用场景列举
示例一: package com; interface Operation { double operateTwoIntNum(int a, int b); } p ...
随机推荐
- Struts工作机制图+OGNL+EL+值栈(Map,对象栈)
struts 值栈 通过get set方法 方便的获取,设置属性值 比如从jsp页面传来的參数...从Action设置jsp所要回显的内容 注意EL表达式,struts2对request进 ...
- 端口映射工具 redir/socat/xinetd - 运维技术 - 开源中国社区
端口映射工具 redir/socat/xinetd - 运维技术 - 开源中国社区 端口映射工具 redir/socat/xinetd 10人收藏此文章, 我要收藏 发表于3天前(2013-08 ...
- Adaboost的几个人脸检测网站
[1]基础学习笔记之opencv(1):opencv中facedetect例子浅析 http://www.cnblogs.com/tornadomeet/archive/2012/03/22/2411 ...
- C#语言实现ArcGIS数据源重置之Set Data Source功能
1.须要:依据选择的Mxd路径和目标数据源路径进行重置数据源.此处以(.Mdb为例): 主要利用到的接口: (1)IMapDocument (2)IMapControl2 (3)IWor ...
- 部署、收回和删除解决方式----STSADM和PowerShell
部署.收回和删除解决方式----STSADM和PowerShell 由于近期总是要部署wsp解决方式,所以常常要用到命令行或者PowerShell.所以有必要将命令集中放在这里.在部署 ...
- Restlet+Fastjson 高速构建轻量级 Java RESTful Webservice
自己入门Java时做过一个小型RESTful Web Service的项目,这里总结一下. 服务的数据交换格式主要採用JSON,服务为REST风格.连接採用Http协议,数据库使用MySQL,OR M ...
- hdu-4833-Best-Financing(DP)
Best Financing Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- PHP上传文件超过了最大文件大小限制导致无法上传成功
最近的研究<HeadFirst PHP & MySQL>第一本书5章"使用存储在文件中的数据",难道当一个文件上传应用程序,发生了错误.即,文件不能成功上传.这 ...
- HighChart学习-更新数据data Series与重绘
一:HighChart介绍 基于JQuery的纯JavaScript的图标库,支持各种图表显示,同时还支持Mootools 与Prototype详细版本支持在这里: JQuery 1.3.2 - 1. ...
- JAVA逆向&反混淆-追查Burpsuite的破解原理(转)
0x00 摘要: 本系列文章通过对BurpLoader的几个版本的逆向分析,分析Burpsuite的破解原理,分析Burpsuite认证体系存在的安全漏洞. 0x01 JD-GUI的用途与缺陷: JD ...