从一开始,说出事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 ...
随机推荐
- Java创建、重命名、删除文件和文件夹(转)
Java的文件操作太基础,缺乏很多实用工具,比如对目录的操作,支持就非常的差了.如果你经常用Java操作文件或文件夹,你会觉得反复编写这些代码是令人沮丧的问题,而且要大量用到递归. 下面是的一个解决方 ...
- ASA基本配置
拓扑如下: ASA5520# show running-config : Saved:ASA Version 8.0(2) !hostname ASA5520enable password 2KFQn ...
- 【C语言疯狂讲义】(八)C语言一维数组
1.数组的基本概念: 同样类型 若干个 有序 由若干个同样类型的数据组成的有序的集合 有序:存储地址连续 下标连续 数组名:用来存放数组首地址的变量 数组元素:构成数组的每个数据 数组的 ...
- HTML表格标签的使用-<table>
<html> <head> <title> 表格标签 </title> <!-- 标签名:table 定义一个表格 子标签:<caption ...
- jquery在元素上收购事件
jquery的给元素绑定的事件能够用data方法取出来 通过$(element).data("events")来获取 // 比方给一个button绑定两个click事件 $(&qu ...
- red hat Linux 使用CentOS yum源更新
red hat linux是商业版软件,没有经过注册是无法使用红帽 yum源更新软件的,使用CentOS源更新操作如下: 1.删除red hat linux 原有的yum 源 rpm -aq | gr ...
- 你有PSD的学位吗? - dp的日志 - 网易博客
你有PSD的学位吗? - dp的日志 - 网易博客 你有PSD的学位吗? 2011-08-01 12:58:40| 分类: 感悟 | 标签:自我提升 |字号 大中小 订阅 去年, ...
- COST CUTTING THE ALAN GREENBERG WAY
AnatBird.com COST CUTTING THE ALAN GREENBERG WAY
- POJ 3652 & ZOJ 2934 & HDU 2721 Persistent Bits(数学 元)
主题链接: PKU:http://poj.org/problem?id=3652 ZJU:http://acm.zju.edu.cn/onlinejudge/showProblem.do? probl ...
- eclipse failed to create the java virtual machine 问题图文解析(转)
clipse failed to create the java virtual machine 解决方法: 1.问题现象 2.java虚拟机初始化失败!寻找eclipse解压路径 3.寻找ecl ...