- 浏览: 577310 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
a1641693970:
还不错,学习了
BeanUtils使用总结(二)LazyDynaBean -
zjfshowtime:
很好的办法,学习了。
ORA-28001: the password has expired -
ya654277yo:
哦,多谢分享
Apache整合Tomcat后get方式提交中文乱码问题解决 -
foolkeeper:
nice !!
jvm内存参数设定 -
tracy821:
谢谢了,找了好久才找到
关于Spring 声明式事务处理时,throws exception不回滚的问题
匿名类与内部类
提起Java内部类(Inner Class)可能很多人不太熟悉,实际上类似的概念在C++里也有,那就是嵌套类(Nested Class),关于这两者的区别与联系,在下文中会有对比。内部类从表面上看,就是在类中又定义了一个类(下文会看到,内部类可以在很多地方定义),而实际上并没有那么简单,乍看上去内部类似乎有些多余,它的用处对于初学者来说可能并不是那么显著,但是随着对它的深入了解,你会发现Java的设计者在内部类身上的确是用心良苦。学会使用内部类,是掌握Java高级编程的一部分,它可以让你更优雅地设计你的程序结构。下面从以下几个方面来介绍:
第一次见面 public interface Contents { int value(); } public interface Destination { String readLabel(); } public class Goods { private class Content implements Contents { private int i = 11; public int value() { return i; } } protected class GDestination implements Destination { private String label; private GDestination(String whereTo) { label = whereTo; } public String readLabel() { return label; } } public Destination dest(String s) { return new GDestination(s); } public Contents cont() { return new Content(); } } class TestGoods { public static void main(String[] args) { Goods p = new Goods(); Contents c = p.cont(); Destination d = p.dest("Beijing"); } } 在这个例子里类Content和GDestination被定义在了类Goods内部,并且分别有着protected和private修饰符来控制访问级别。Content代表着Goods的内容,而GDestination代表着Goods的目的地。它们分别实现了两个接口Content和Destination。在后面的main方法里,直接用 Contents c和Destination d进行操作,你甚至连这两个内部类的名字都没有看见!这样,内部类的第一个好处就体现出来了——隐藏你不想让别人知道的操作,也即封装性。 同时,我们也发现了在外部类作用范围之外得到内部类对象的第一个方法,那就是利用其外部类的方法创建并返回。上例中的cont()和dest()方法就是这么做的。那么还有没有别的方法呢?当然有,其语法格式如下: outerObject=new outerClass(Constructor Parameters); outerClass.innerClass innerObject=outerObject.new InnerClass(Constructor Parameters); 注意在创建非静态内部类对象时,一定要先创建起相应的外部类对象。至于原因,也就引出了我们下一个话题—— 非静态内部类对象有着指向其外部类对象的引用 对刚才的例子稍作修改: public class Goods { private valueRate=2; private class Content implements Contents { private int i = 11*valueRate; public int value() { return i; } } protected class GDestination implements Destination { private String label; private GDestination(String whereTo) { label = whereTo; } public String readLabel() { return label; } } public Destination dest(String s) { return new GDestination(s); } public Contents cont() { return new Content(); } } 修改的部分用蓝色显示了。在这里我们给Goods类增加了一个private成员变量valueRate,意义是货物的价值系数,在内部类Content的方法value()计算价值时把它乘上。我们发现,value()可以访问valueRate,这也是内部类的第二个好处——一个内部类对象可以访问创建它的外部类对象的内容,甚至包括私有变量!这是一个非常有用的特性,为我们在设计时提供了更多的思路和捷径。要想实现这个功能,内部类对象就必须有指向外部类对象的引用。Java编译器在创建内部类对象时,隐式的把其外部类对象的引用也传了进去并一直保存着。这样就使得内部类对象始终可以访问其外部类对象,同时这也是为什么在外部类作用范围之外向要创建内部类对象必须先创建其外部类对象的原因。 有人会问,如果内部类里的一个成员变量与外部类的一个成员变量同名,也即外部类的同名成员变量被屏蔽了,怎么办?没事,Java里用如下格式表达外部类的引用: outerClass.this 有了它,我们就不怕这种屏蔽的情况了。 静态内部类 和普通的类一样,内部类也可以有静态的。不过和非静态内部类相比,区别就在于静态内部类没有了指向外部的引用。这实际上和C++中的嵌套类很相像了,Java内部类与C++嵌套类最大的不同就在于是否有指向外部的引用这一点上,当然从设计的角度以及以它一些细节来讲还有区别。 除此之外,在任何非静态内部类中,都不能有静态数据,静态方法或者又一个静态内部类(内部类的嵌套可以不止一层)。不过静态内部类中却可以拥有这一切。这也算是两者的第二个区别吧。 局部内部类 是的,Java内部类也可以是局部的,它可以定义在一个方法甚至一个代码块之内。 public class Goods1 { public Destination dest(String s) { class GDestination implements Destination { private String label; private GDestination(String whereTo) { label = whereTo; } public String readLabel() { return label; } } return new GDestination(s); } public static void main(String[] args) { Goods1 g= new Goods1(); Destination d = g.dest("Beijing"); } } 上面就是这样一个例子。在方法dest中我们定义了一个内部类,最后由这个方法返回这个内部类的对象。如果我们在用一个内部类的时候仅需要创建它的一个对象并创给外部,就可以这样做。当然,定义在方法中的内部类可以使设计多样化,用途绝不仅仅在这一点。 下面有一个更怪的例子: 内部类可以通过程序控制其存在域 public class Goods2{ private void internalTracking(boolean b) { if(b) { class TrackingSlip { private String id; TrackingSlip(String s) { id = s; } String getSlip() { return id; } } TrackingSlip ts = new TrackingSlip("slip"); String s = ts.getSlip(); } } public void track() { internalTracking(true); } public static void main(String[] args) { Goods2 g= new Goods2(); g.track(); } } 你不能在if之外创建这个内部类的对象,因为这已经超出了它的作用域。不过在编译的时候,内部类TrackingSlip和其他类一样同时被编译,只不过它由它自己的作用域,超出了这个范围就无效,除此之外它和其他内部类并没有区别。 匿名内部类 java的匿名内部类的语法规则看上去有些古怪,不过如同匿名数组一样,当你只需要创建一个类的对象而且用不上它的名字时,使用内部类可以使代码看上去简洁清楚。它的语法规则是这样的: new interfacename(){......}; 或 new superclassname(){......}; 下面接着前面继续举例子: public class Goods3 { public Contents cont(){ return new Contents(){ private int i = 11; public int value() { return i; } }; } } 这里方法cont()使用匿名内部类直接返回了一个实现了接口Contents的类的对象,看上去的确十分简洁。 在java的事件处理的匿名适配器中,匿名内部类被大量的使用。例如在想关闭窗口时加上这样一句代码: frame.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); } }); 有一点需要注意的是,匿名内部类由于没有名字,所以它没有构造函数(但是如果这个匿名内部类继承了一个只含有带参数构造函数的父类,创建它的时候必须带上这些参数,并在实现的过程中使用super关键字调用相应的内容)。 如果你想要初始化它的成员变量,有下面几种方法:
(1)如果是在一个方法的匿名内部类,可以利用这个方法传进你想要的参数,不过记住,这些参数必须被声明为final。 如果没有final的话,那么内部类使用的外部类局部变量要用哪个值呢? 另外引用别人的一段话: (2)将匿名内部类改造成有名字的局部内部类,这样它就可以拥有构造函数了。
在这个匿名内部类中使用初始化代码块。 为什么需要内部类? java内部类有什么好处?为什么需要内部类? 首先举一个简单的例子,如果你想实现一个接口,但是这个接口中的一个方法和你构想的这个类中的一个方法的名称,参数相同,你应该怎么办?这时候,你可以建一个内部类实现这个接口。由于内部类对外部类的所有内容都是可访问的,所以这样做可以完成所有你直接实现这个接口的功能。 不过你可能要质疑,更改一下方法的不就行了吗? 的确,以此作为设计内部类的理由,实在没有说服力。 真正的原因是这样的,java中的内部类和接口加在一起,可以的解决常被C++程序员抱怨java中存在的一个问题——没有多继承。实际上,C++的多继承设计起来很复杂,而java通过内部类加上接口,可以很好的实现多继承的效果。 |
发表评论
-
BCD Conversion in java
2016-03-31 23:39 1841/** * Copyright 2010 Firat ... -
在java代码中获取JVM参数
2014-04-08 11:16 14258近日关注性能调优,关注JMX,发现java.lang.man ... -
GC日志分析配置与工具
2013-05-08 11:32 1358-verbose:gc(打印GC日志) -Xloggc:( ... -
java 实现HTTP PROXY
2012-12-06 17:21 7582日常应用中使用过很多次代理,主要停留在配置级别。 近期无意看 ... -
运行时获取方法调用堆栈信息(java)
2012-09-14 10:53 9700前几日系统流程回调时,一个方法莫名其妙被调用,无法定位调用点。 ... -
EL表达式在tomcat7.0下的new关键字不能使用
2012-08-24 17:25 4066最近生产系统部署个小应用,服务器选型tomcat7.0,一直运 ... -
xfire设置连接超时问题
2012-08-01 17:25 5151近期使用xfire作为客户端访问WS,结果因为目标主机假死 ... -
将多个对象写到一个文件
2012-07-20 17:08 1250来看一段ObjectOutputStream构造方法的源代码 ... -
多线程学习笔记:synchronized
2011-12-15 17:32 844Java语言的关键字,当它 ... -
(转)使用 Eclipse Memory Analyzer 检测内存泄漏问题
2011-12-14 18:10 1146本文是关于在开发 Talend RCP 过程中碰 ... -
多线程学习笔记:thread 线程中的sleep()、wait()、yield()、join()
2011-12-14 17:46 12821.sleep()方法 在指定时间内让当前正在执行的线程暂 ... -
jconsole监控JVM
2011-12-12 17:46 1566本地监控: Jconsole [processed] ... -
Java 6 JVM参数选项大全(中文版)
2011-11-03 15:19 1040本文 是基于最新的SUN官方 文档Java SE 6 ... -
Java实现远程屏幕监视
2011-10-19 17:40 734Robot robot = new Robot(); / ... -
java线程池 常用方法
2011-09-24 22:52 1392在Java5之后,并发线程这块发生了根本的变化,最重要的莫过于 ... -
JAVA 调用Web Service的方法
2011-08-15 10:28 11571.使用HttpClient 用到的jar文件:comm ... -
JVM监控工具--jvmstat
2011-08-02 15:42 1280首先就是下载这个工具链接:http://java.sun.co ... -
java性能优化
2011-07-18 15:19 1108一、避免在循环条件中 ... -
jvm内存参数设定
2011-07-17 20:30 1383在开发java应用时经常出 ... -
怎样解决Java内存泄漏
2011-07-15 11:38 1459解决Java 内存泄漏 Java内存泄漏是每个 ...
相关推荐
Java 中的匿名内部类是一种特殊的内部类,它没有名字,因此也称为匿名类。匿名内部类是一种简洁的编程方式,能够简化代码编写,但它也有一些限制和特点。 匿名内部类的定义 匿名内部类是指没有名字的内部类,它是...
3. **匿名内部类与接口** 匿名内部类可以用来快速实现一个接口的所有方法,这对于实现简单的回调逻辑非常方便。例如,处理按钮点击事件: ```java button.setOnClickListener(new View.OnClickListener() { @...
Java匿名内部类是Java语言中一个独特且强大的特性,它允许我们在不需要定义一个单独的类的情况下创建类的实例。这在处理回调、事件监听、单例模式以及其他需要短时间内定义一个简单类的情况时非常有用。本篇文章将...
总结来说,MapReduce是大数据处理的关键技术,泛型提供了强大的类型安全和代码复用,匿名内部类简化了多线程编程,而`Runnable`和`Callable`则是Java多线程编程的基础。了解和掌握这些概念对于理解现代分布式系统和...
Java 基础第七章内部类与异常类 Java 语言支持在一个类中定义另一个类,这样的类称做内部类。内部类和外嵌类之间存在着紧密的关系:内部类可以访问外嵌类的成员变量和方法,而外嵌类也可以使用内部类声明的对象作为...
Java匿名对象与匿名内部类 Java匿名对象是指没有名字的对象,非匿名对象则是具有名字的对象。在Java中,我们可以使用匿名对象来简化代码,并减少内存的使用。匿名对象的使用场景包括:当对象对方法仅进行一次调用的...
适配器模式结合匿名内部类,可以让我们快速地将一个对象转换为期望的接口,以便与已有系统兼容。 描述中的"使用适配器类(匿名内部类)"可能是指创建了一个匿名内部类,该类实现了某个接口或继承了某个类,以便将...
首先,内部类分为四种类型:成员内部类、局部内部类、匿名内部类和静态内部类。成员内部类就像其他成员变量一样,可以直接访问外部类的所有成员,包括私有成员。局部内部类只存在于某个方法内,它的作用范围更小,...
本讲义将深入探讨Java中的匿名内部类与适配器模式,这两种概念在实际开发中都有着广泛的用途。 首先,让我们了解一下匿名内部类。匿名内部类,顾名思义,就是没有名字的类,它可以在需要使用类的地方直接定义,无需...
Java 基础第七章 -内部类与异常类 本章节主要讲解 Java 的内部类和异常类的概念、特点、使用方法和注意事项。 内部类 ------ 内部类是 Java 支持的一种特殊类,定义在另一个类的内部。内部类和外嵌类之间存在关系...
内部类分为四种类型:成员内部类、局部内部类、匿名内部类和静态嵌套类。其中,静态嵌套类是与外部类关联但不持有对外部类的引用,因此它可以像普通类一样被静态引用,而无需外部类实例。 Java的静态嵌套类通常用于...
内部类分为四种类型:成员内部类、局部内部类、匿名内部类和静态内部类。控制器通常会用到的是成员内部类或静态内部类,因为它们可以访问外部类的属性和方法,同时又具有一定的封装性。 1. **成员内部类**:这种...
内部类(Inner Classes)是定义在另一个类或接口中的类,它们主要分为四种类型:成员内部类、静态嵌套类、方法内部类和匿名内部类。这些内部类在功能上具有一定的共性,同时又各具特色,适用于不同的场景。 **共性...
静态内部类与普通成员内部类的区别在于,它可以包含静态成员。它同样可以访问外部类的所有静态成员,但不能直接访问外部类的实例成员。创建静态内部类的对象时,可以直接使用`内部类类名 对象名 = new 外部类类名....
虽然Java的字节码可能看起来与C#的有所不同,但其核心思想是一样的:通过匿名类来实现回调或事件处理。 总结来说,C#的匿名委托和Java的匿名局部内部类都提供了一种简洁的方式来定义一次性使用的函数或方法。它们都...
局部内部类与成员内部类相似,但是它的生命周期随着方法或代码块的执行结束而结束。 - **定义在方法上**: ```java public void method() { class LocalInnerClass { public void doSomething() { System.out...
### Java软件开发实战:内部类与包装器 #### 8-1 内部类与包装器 ##### 内部类概述 内部类是Java中一种特殊的类,它被定义在另一个类(称为外部类)中。内部类可以分为四种类型:静态内部类、非静态内部类、局部...
3. 静态内部类:与成员内部类类似,但可以像普通静态成员一样被实例化,无需外部类的实例。 4. 匿名内部类:没有名字的内部类,通常用于快速创建一次性使用的类,尤其是在实现接口时。 内部类的主要优点在于它们...
例如,下面的Lambda表达式与上面的匿名内部类等价: ```java button.addActionListener(e -> System.out.println("Button clicked!")); ``` 这里的Lambda表达式`e -> System.out.println("Button clicked!")`接收一...