从一开始,说出事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 ...
随机推荐
- cocos2dX 之CCParticle
今天我们来看看粒子特效, 何为粒子特效, 为了模拟燃烧的火焰, 天空飘下来的血环, 滴落的小雨, 这些无规律变化的物体, 我们引进了粒子特效这个名词, 粒子特效的原理是将无数的单个粒子组合使其呈现出固 ...
- .idata数据的解析
每类Section代表不同的数据,不同的数据存储组织方式一定是有非常大区别的.代码段与资源段一定区别巨大,这意味着我需要一个一个的学习每个段的解析. idata段解析 这个段主要存储的是导入符号信息. ...
- .Net程序猿乐Android开发---(4)注册页面布局
接下来我们介绍的登陆页面布局,在本节中,我们看一下注册页面布局,页面布局大同小异,来一起熟悉下基本控件的使用方法. 效果图: 1.加入注冊页面 右键选中layout目录,加入注冊页面.例如以下图 点击 ...
- 【Nginx】启动过程
从应用程序的启动过程中main功能开始跟踪. 解析命令行參数并保存到ngx_cycle_t结构体中,在ngx_process_options函数中将保存配置文件路径. 调用ngx_add_inheri ...
- SpringMVC配置+小例子
先加入SpringMVC的jar包,这个官网上有,下载下来放到lib文件夹下. web.xml文件: <?xml version="1.0" encoding="U ...
- libsvm中的dec_values以及分类结果评分问题
最近一个图像识别项目里需要对分类的结果进行打分,因为使用的是libsvm3.12,一开始决定直接将svm_predict_values函数的dec_values作为评分返回,后来研究了之后才觉得里面有 ...
- hdu4004(二分)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4004 大致题意 二分最大跳跃能力,判断是否可以在m次内到达对岸! 分析:由于求青蛙最小弹跳能力,所以二 ...
- Winsock 编程流程
近期看了<Window程序设计>感觉在网络方面讲的不错,讲的非常通俗易懂.与大家一同交流 转载请注明出处:http://blog.csdn.net/u010484477谢谢^_^ 使用 W ...
- ServiceCallSite
ServiceCallSite 通过上一篇的介绍我们应该对实现在ServiceProvider的总体设计有了一个大致的了解,但是我们刻意回避一个重要的话题,即服务实例最终究竟是采用何种方式提供出来的. ...
- Eclipse设置的断点失效的解决办法
使用Eclipse的同胞们,如果你哪天惊奇的发现调试时,明明设置了断点,按道理就是要执行设置断点的那条语句的,可是偏偏Eclipse视你设置的断点不见,不要害怕,不要恐慌,这样的问题不应该导致偶们疯狂 ...