【转】Java 内部类种类及使用解析
Java 内部类种类及使用解析
内部类Inner Class
将相关的类组织在一起,从而降低了命名空间的混乱。
一个内部类可以定义在另一个类里,可以定义在函数里,甚至可以作为一个表达式的一部分。
Java中的内部类共分为四种:
静态内部类static inner class (also called nested class)
成员内部类member inner class
局部内部类local inner class
匿名内部类anonymous inner class
静态内部类Static Inner Class
最简单的内部类形式。
类定义时加上static关键字。
不能和外部类有相同的名字。
被编译成一个完全独立的.class文件,名称为OuterClass$InnerClass.class的形式。
只可以访问外部类的静态成员和静态方法,包括了私有的静态成员和方法。
生成静态内部类对象的方式为:
OuterClass.InnerClass inner = new OuterClass.InnerClass();
静态内部类使用代码:
![](https://common.cnblogs.com/images/copycode.gif)
package com.learnjava.innerclass; class StaticInner
{
private static int a = 4; // 静态内部类
public static class Inner
{
public void test()
{
// 静态内部类可以访问外部类的静态成员
// 并且它只能访问静态的
System.out.println(a);
} }
} public class StaticInnerClassTest
{ public static void main(String[] args)
{
StaticInner.Inner inner = new StaticInner.Inner();
inner.test();
}
}
![](https://common.cnblogs.com/images/copycode.gif)
成员内部类Member Inner Class
成员内部类也是定义在另一个类中,但是定义时不用static修饰。
成员内部类和静态内部类可以类比为非静态的成员变量和静态的成员变量。
成员内部类就像一个实例变量。
它可以访问它的外部类的所有成员变量和方法,不管是静态的还是非静态的都可以。
在外部类里面创建成员内部类的实例:
this.new Innerclass();
在外部类之外创建内部类的实例:
(new Outerclass()).new Innerclass();
在内部类里访问外部类的成员:
Outerclass.this.member
详情见代码例子:
![](https://common.cnblogs.com/images/copycode.gif)
package com.learnjava.innerclass; class MemberInner
{
private int d = 1;
private int a = 2; // 定义一个成员内部类
public class Inner2
{
private int a = 8; public void doSomething()
{
// 直接访问外部类对象
System.out.println(d);
System.out.println(a);// 直接访问a,则访问的是内部类里的a // 如何访问到外部类里的a呢?
System.out.println(MemberInner.this.a);
} } } public class MemberInnerClassTest
{ public static void main(String[] args)
{ // 创建成员内部类的对象
// 需要先创建外部类的实例
MemberInner.Inner2 inner = new MemberInner().new Inner2(); inner.doSomething();
}
}
![](https://common.cnblogs.com/images/copycode.gif)
局部内部类Local Inner Class
局部内部类定义在方法中,比方法的范围还小。是内部类中最少用到的一种类型。
像局部变量一样,不能被public, protected, private和static修饰。
只能访问方法中定义的final类型的局部变量。
局部内部类在方法中定义,所以只能在方法中使用,即只能在方法当中生成局部内部类的实例并且调用其方法。
![](https://common.cnblogs.com/images/copycode.gif)
package com.learnjava.innerclass; class LocalInner
{
int a = 1; public void doSomething()
{
int b = 2;
final int c = 3;
// 定义一个局部内部类
class Inner3
{
public void test()
{
System.out.println("Hello World");
System.out.println(a); // 不可以访问非final的局部变量
// error: Cannot refer to a non-final variable b inside an inner
// class defined in a different method
// System.out.println(b); // 可以访问final变量
System.out.println(c);
}
} // 创建局部内部类的实例并调用方法
new Inner3().test();
}
} public class LocalInnerClassTest
{
public static void main(String[] args)
{
// 创建外部类对象
LocalInner inner = new LocalInner();
// 调用外部类的方法
inner.doSomething();
} }
![](https://common.cnblogs.com/images/copycode.gif)
匿名内部类Anonymous Inner Class
匿名内部类就是没有名字的局部内部类,不使用关键字class, extends, implements, 没有构造方法。
匿名内部类隐式地继承了一个父类或者实现了一个接口。
匿名内部类使用得比较多,通常是作为一个方法参数。
![](https://common.cnblogs.com/images/copycode.gif)
package com.learnjava.innerclass; import java.util.Date; public class AnonymouseInnerClass
{ @SuppressWarnings("deprecation")
public String getDate(Date date)
{
return date.toLocaleString(); } public static void main(String[] args)
{
AnonymouseInnerClass test = new AnonymouseInnerClass(); // 打印日期:
String str = test.getDate(new Date());
System.out.println(str);
System.out.println("----------------"); // 使用匿名内部类
String str2 = test.getDate(new Date()
{
});// 使用了花括号,但是不填入内容,执行结果和上面的完全一致
// 生成了一个继承了Date类的子类的对象
System.out.println(str2);
System.out.println("----------------"); // 使用匿名内部类,并且重写父类中的方法
String str3 = test.getDate(new Date()
{ // 重写父类中的方法
@Override
@Deprecated
public String toLocaleString()
{
return "Hello: " + super.toLocaleString();
} }); System.out.println(str3);
}
}
![](https://common.cnblogs.com/images/copycode.gif)
生成的.class文件中,匿名类会生成OuterClass$1.class文件,数字根据是第几个匿名类而类推。
Swing中使用内部类的例子如下:
![](https://common.cnblogs.com/images/copycode.gif)
package com.learnjava.innerclass; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import javax.swing.JButton;
import javax.swing.JFrame; public class SwingTest
{
public static void main(String[] args)
{
JFrame frame = new JFrame("JFrame");
JButton button = new JButton("JButton"); button.addActionListener(new ActionListener()
{
// new出来一个实现了ActionListener接口的类的实例 @Override
public void actionPerformed(ActionEvent arg0)
{
System.out.println("Hello World"); }
}); //加入按钮
frame.getContentPane().add(button); //设置关闭行为
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(200, 200); frame.addWindowListener(new WindowAdapter()
{
//也可以使用继承了适配器类的匿名内部类
@Override
public void windowClosing(WindowEvent e)
{ System.out.println("Closing");
System.exit(0);
}
});
frame.setVisible(true);
} }
![](https://common.cnblogs.com/images/copycode.gif)
【转】Java 内部类种类及使用解析的更多相关文章
- Java 内部类种类及使用解析【转】
内部类Inner Class 将相关的类组织在一起,从而降低了命名空间的混乱. 一个内部类可以定义在另一个类里,可以定义在函数里,甚至可以作为一个表达式的一部分. Java中的内部类共分为四种: 静态 ...
- 深入java面向对象四:Java 内部类种类及使用解析(转)
内部类Inner Class 将相关的类组织在一起,从而降低了命名空间的混乱. 一个内部类可以定义在另一个类里,可以定义在函数里,甚至可以作为一个表达式的一部分. Java中的内部类共分为四种: 静态 ...
- Java 内部类种类及使用解析
package com.learnjava.innerclass; class MemberInner { private int d = 1; private int a = 2; // 定义一个成 ...
- Java内部类的基本解析
内部类 内部类的基本概念 所谓的内部类也就是在一个类的内部进行其他类结构的嵌套操作. 为什么要使用内部类? 这就要引用一句十分著名的一本书叫<Think in java>中的一句名言了—— ...
- JAVA内部类(转)
源出处:JAVA内部类 在java语言中,有一种类叫做内部类(inner class),也称为嵌入类(nested class),它是定义在其他类的内部.内部类作为其外部类的一个成员,与其他成员一样, ...
- Java线程Thread的状态解析以及状态转换分析 多线程中篇(七)
线程与操作系统中线程(进程)的概念同根同源,尽管千差万别. 操作系统中有状态以及状态的切换,Java线程中照样也有. State 在Thread类中有内部类 枚举State,用于抽象描述Java线程的 ...
- Java 内部类.md
Java 内部类 学习自 <Java编程思想> Overview 什么是内部类? Thinking In Java 中如此定义: 将一个类的定义放在里另一个类的定义的内部,这就是内部类. ...
- 使用java自带的xml解析器解析xml
使用java自带的xml解析器解析xml,其实我不推荐,可以用Dom解析,或其他的方式,因为Java自带的解析器使用不但麻烦,且还有bug出现. 它要求,针对不同的xml(结构不同),必须写对应的ha ...
- Java内部类final语义实现
本文描述在java内部类中,经常会引用外部类的变量信息.但是这些变量信息是如何传递给内部类的,在表面上并没有相应的线索.本文从字节码层描述在内部类中是如何实现这些语义的. 本地临时变量 基本类型 fi ...
随机推荐
- 6、Spring+Struts2+MyBatis(mybatis有代理)整合增删改查
1.创建如下的oracle脚本 create table userinfo (id ), name ), password telephone ), isadmin )); --4.2 用户表序列 c ...
- 朱丽叶—Cuda+OSG
#include <cuda_runtime.h> #include <osg/Image> ; typedef struct cuComplex { float r; flo ...
- inode和文件描述符区别
inode 或i节点是指对文件的索引.如一个系统,所有文件是放在磁盘或flash上,就要编个目录来说明每个文件在什么地方,有什么属性,及大小等.就像书本的目录一样,便于查找和管理.这目录是操作系统需要 ...
- MVC中发生System.Data.Entity.Validation.DbEntityValidationException验证异常的解决方法
发生System.Data.Entity.Validation.DbEntityValidationException这个异常的时候,如果没有用特定的异常类去捕捉,是看不到具体信息的. 通常都是用Sy ...
- C/C++ - <string> 与<string.h>、<cstring>的区别
<string.h><string.h>是C版本的头文件,包含比如strcpy.strcat之类的字符串处理函数. <string><string>是C ...
- 2016NEFU集训第n+3场 E - New Reform
Description Berland has n cities connected by m bidirectional roads. No road connects a city to itse ...
- SharePoint 2013 工作流设计之Designer 使用“可视化视图
转载自:http://www.cnblogs.com/jianyus/p/3406309.html SharePoint 2013增强了工作流功能,而Designer里面也添加了可视化设计视图,也就是 ...
- ADO.NET基础、数据增删改查
ADO.NET:数据访问技术,就是将C#和MSSQL连接起来的一个纽带.我们可以通过ADO.NET将内存中的临时数据写入到数据库中,也可以将数据库中的数据提取到内存中供程序调用. 数据库数据的增.删. ...
- 移动端touch事件影响click事件的相关解决方法
preventDefault()的方法,阻止事件的默认行为. 在移动端,手指点击一个元素,会经过:touchstart --> touchmove -> touchend -->cl ...
- javaWEB总结(1):第一个servlet程序
1.新建一个javaWeb工程,工程的目录如下 2.在com.dao.chu的包下新建一个HelloServlet.java类 package com.dao.chu; import java.io. ...