什么是javajava 匿名内部类类

关注51Testing
Java内部类的一些总结
发表于: 10:17 &作者:codersai & 来源:51Testing软件测试网采编
推荐标签:
  作为刚入门Java的小白,这两天看到内部类,这里做一个总结,若有错误,欢迎指正~  内部类是指在一个外部类的内部再定义一个类。类名不需要和文件夹相同。  内部类分为: 成员内部类、局部内部类、静态嵌套类、匿名内部类 。  1.成员内部类  成员内部类是最普通的内部类,它的定义为位于另一个类的内部,形如下面的形式:  class Outter {  private int age = 12;  class Inner {  private int age = 13;  public void print() {  int age = 14;  System.out.println("局部变量:" + age);  System.out.println("内部类变量:" + this.age);  System.out.println("外部类变量:" + Outter.this.age);  }  }  }  public class test1 {  public static void main(String[] args) {  Outter out = new Outter();  Outter.Inner in = out.new Inner();  in.print();  }  }  运行结果:  局部变量:14  内部类变量:13  外部类变量:12  从本例可以看出:成员内部类,就是作为外部类的成员,可以直接使用外部类的所有成员和方法,即使是private的。虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问:  class Outter {  private int age = 12;  public Outter(int age) {  this.age =  getInInstance().print(); & //必须先创建成员内部类的对象,再进行访问!  }  private Inner getInInstance() {  return new Inner();  }  class Inner {  public void print() {  System.out.println("内部类没同名,所以直接调用外部类成员变量:" + age);  }  }  }  public class test1 {  public static void main(String[] args) {  Outter out = new Outter(10);  }  }  运行结果:  内部类没同名,所以直接调用外部类成员变量:10  内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。  比如上面的例子,如果成员内部类Inner用private修饰,则只能在外部类的内部访问,如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。  这一点和外部类有一点不一样,外部类只能被public和包访问两种权限修饰。  我个人是这么理解的,由于成员内部类看起来像是外部类的一个成员,所以可以像类的成员一样拥有多种权限修饰。要注意的是,成员内部类不能含有static的变量和方法。因为成员内部类需要先创建了外部类,才能创建它自己的
搜索风云榜
51Testing官方微信
51Testing官方微博
测试知识全知道匿名用户不能发表回复!|参考我最喜欢的一本书,李刚《疯狂java讲义》第6章
一.内部类的访问控制修饰符
1.外部类的上一级单元是包,所以它只有两个作用域:同一个包内和任何位置。所以外部类有包访问权限(即默认的,没有修饰符)和public。
2.内部类的上一级程序单元是外部类,它有四个作用域:同一个类private,同一个包default,父子类protected和public
二.非静态内部类
1.非静态内部类的方法访问某个变量时,系统查找顺序为:
  该方法内的局部变量 &--〉 &内部类的局部变量 &--〉 &外部类的成员变量,都查找不到则编译出错。
  如果外部类成员变量、内部类成员变量、内部类里的方法的局部变量重名,则可用外部类类名.this、this作为限定来区分。
1 public class OutClass {
private String str = "外部类的成员变量";
private class InClass{
private String str = "内布类的成员变量";
public void test(){
String str = "局部变量";
//通过外部类类名.this.varName 访问外部类实例变量
System.out.println(OutClass.this.str);
//通过this.varName 访问内部类实例变量
<span style="color: #
System.out.println(this.str);
<span style="color: #
//直接访问局部变量
<span style="color: #
System.out.println(str);
<span style="color: #
<span style="color: #
<span style="color: #
<span style="color: #
public static void main(String[] args) {
<span style="color: #
new OutClass().new InClass().test();
<span style="color: #
<span style="color: # }
输出结果为:
外部类的成员变量内布类的成员变量局部变量
2.非静态内部类的成员可以访问外部类的private成员,但反过来就不成立了。而且非静态内部类public成员也不可以被外部类直接访问。
非静态内部类的成员只有在非静态内部类范围内可知,并不能被外部类直接使用。可以通过创建非静态内部类对象来调用访问其实例成员。
**非静态内部类对象必须寄生在外部类对象里,而外部类对象则不一定有非静态内部类对象寄生其中。因此外部类对象访问非静态内部类成员时,可能非静态内部类对象根本不存在!而非静态内部类对象访问外部类成员时,外部类对象一定存在。
<span style="color: #.非静态内部类里不能有静态方法、静态成员变量、静态初始化块,可以包含普通初始化块。
二.静态内部类
<span style="color: #.静态内部类访问外部类
静态内部类可以包含静态成员,也可以包含非静态成员。根据静态成员不能访问非静态成员的规则,静态内部类不能访问外部类的实力成员,只能访问外部类的类成员,即使是静态内部类的实例方法也不可访问外部类的实例成员。
<span style="color: #.外部类访问静态内部类
外部类依然不能直接访问静态内部类成员,但可以使用静态内部类的类名作为调用者来访问静态内部类的静态成员,也可以使用静态内部类对象作为调用者来访问静态内部类的实例成员。
*静态内部类是外部类的类相关的,而不是外部类的对象相关的。也就是说,静态内部类对象不是寄生在外部类的实例中,而是寄生在外部类的类本身中。当静态内部类对象存在时,并不存在一个被它寄生的外部类对象。静态内部类对象只持有外部类的类引用,没有外部类对象的引用。
三.在外部类以外使用内部类
1.访问权限
默认(default):只能被与外部类处于同一个包中的其他类访问。
protected:可被与外部类处于同一个包中的其他类和外部类的子类访问。
<span style="color: #.在外部类以外使用非静态内部类
非静态内部类需要寄生在外部类的对象里,所以创建非静态内部类对象之前需要先创建外部类对象,语法如下:
Out.In in = new Out().new In(); 也可以拆成两步,即:
Out out = new Out();
Out.In in = out.new In();
3.在外部类以外使用静态内部类
因为静态内部类是外部类的类相关的,因此创建静态内部类对象时无需创建外部类对象,语法如下:
Out.StaticOutIn in = new Out.StaticIn();
&四.匿名内部类
new 接口()|抽象类构造器(参数列表)|父类构造器(参数列表){
  //匿名内部类的类体部分
由此可知:匿名内部类必须且只能继承一个父类或实现一个接口或者实现一个抽象类。
由于匿名内部类没有类名,所以不能定义构造器,但匿名内部类可以定义初始化块来完成构造器需要完成的事情。
2.final修饰的局部变量才可被匿名内部类使用
3 public class Test {
public void testClass(TestClass t){
System.out.println("已进入testClass------------------------");
public void testAbstract(TestAbstract t){
<span style="color: #
System.out.println("已进入testAbstract------------------------");
<span style="color: #
t.test("===抽象类测试方法");
<span style="color: #
<span style="color: #
<span style="color: #
public void testInterface(TestInterface t){
<span style="color: #
System.out.println("已进入testInterface------------------------");
<span style="color: #
t.test("===接口测试方法");
<span style="color: #
<span style="color: #
<span style="color: #
public static void main(String[] args) {
<span style="color: #
Test t = new Test();
<span style="color: #
//final修饰的局部变量才可被匿名内部类使用,(Java8更智能可以自己加)
<span style="color: #
final String str = "局部变量";
<span style="color: #
//测试继承类,并在匿名内部类中重写父类测试方法
<span style="color: #
t.testClass(new TestClass("---被匿名内部类测试中。。。"){
<span style="color: #
public void test(){
<span style="color: #
System.out.println("继承类时的匿名内部类重写测试方法");
<span style="color: #
System.out.println("测试在匿名内部类中使用局部变量-=-=-"+str);
<span style="color: #
<span style="color: #
<span style="color: #
<span style="color: #
//测试实现抽象类,并在匿名内部类中重写抽象类测试方法
<span style="color: #
t.testAbstract(new TestAbstract("---被匿名内部类测试中。。。"){
<span style="color: #
<span style="color: #
<span style="color: #
//匿名内部类实现抽象类时必须重写其抽象方法
<span style="color: #
void test(String str) {
<span style="color: #
// TODO Auto-generated method stub
<span style="color: #
System.out.println("匿名内部类重写的抽象类测试方法"+str);
<span style="color: #
<span style="color: #
<span style="color: #
<span style="color: #
<span style="color: #
//测试实现接口
<span style="color: #
t.testInterface(new TestInterface(){
<span style="color: #
<span style="color: #
<span style="color: #
//匿名内部类实现接口时必须重写其抽象方法
<span style="color: #
public void test(String str) {
<span style="color: #
// TODO Auto-generated method stub
<span style="color: #
System.out.println("匿名内部类重写的接口测试方法"+str);
<span style="color: #
<span style="color: #
<span style="color: #
<span style="color: #
<span style="color: #
<span style="color: # }
<span style="color: #
<span style="color: # class TestClass{
<span style="color: #
public TestClass(String str){
<span style="color: #
System.out.println("父类有参构造器"+str);
<span style="color: #
<span style="color: #
<span style="color: #
public void test(){
<span style="color: #
System.out.println("父类测试方法");
<span style="color: #
<span style="color: # }
<span style="color: # abstract class TestAbstract{
<span style="color: #
public TestAbstract(String str){
<span style="color: #
System.out.println("抽象类有参构造器"+str);
<span style="color: #
<span style="color: #
abstract void test(String str);
<span style="color: # }
<span style="color: # interface TestInterface{
<span style="color: #
void test(String str);
<span style="color: # }
<span style="color: # 运行结果:
<span style="color: # 父类有参构造器---被匿名内部类测试中。。。
<span style="color: # 已进入testClass------------------------
<span style="color: # 继承类时的匿名内部类重写测试方法
<span style="color: # 测试在匿名内部类中使用局部变量-=-=-局部变量
<span style="color: # 抽象类有参构造器---被匿名内部类测试中。。。
<span style="color: # 已进入testAbstract------------------------
<span style="color: # 匿名内部类重写的抽象类测试方法===抽象类测试方法
<span style="color: # 已进入testInterface------------------------
<span style="color: # 匿名内部类重写的接口测试方法===接口测试方法
阅读(...) 评论()什么时候,什么情况要用内部类
内部类是java的一个特性,他为开发者提供了优雅的编码方式,也提供了最大限度的安全保护手段
(1)内部类只能间接通过访问外部类的方法来实例化内部类
(2)内部类可以直接外部类的私有和保护属性,方便实用
(3)内部类可以减少开发类的数量
内部类是个很好的工具,当然它的功能可以使用公共类的方式取代,但是它的使用是很广泛的,建议你还是认真学学
其他答案(共3个回答)
需要实现某些接口
的时候 而且
这个类只在局部使用
或只是用一次的时候用
内部类的共性
  内部类分为: 成员内部类、静态嵌套类、方法内部类、匿名内部类。
  (1)、内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.cla...
亲,你可以实例化对象,然后调用类方法
本文讨论的不是内部类的概念,而是具体使用的一个场景-如何在内部类中返回外部对象
看一段代码
import java.util.LinkedL
Java内部类其实在J2EE编程中使用较少,不过在窗口应用编程中特别常见,主要用来事件的处理。其实,做非GUI编程,内部类完全可以不用。
内部类的声明、访问控制...
void sort(int *p, int n){
for(i=0;ip[j]){
int q=p[i];
p[i]=p[j];
答: 目测是java位数和系统位数不一致一个是32,一个是64
答: 初三水平学编程很难吗?必须需要高数才行吗?
初三当然可以了,跟高数没有关系的。
放心吧!!
答: 网景导航者年时推出了版本4.0,大幅度的强化JavaScript再度强化其功能,但同时出现的bug和CSS的误译,使得占有率渐渐被Intern...
大家还关注
Copyright &
Corporation, All Rights Reserved
确定举报此问题
举报原因(必选):
广告或垃圾信息
激进时政或意识形态话题
不雅词句或人身攻击
侵犯他人隐私
其它违法和不良信息
报告,这不是个问题
报告原因(必选):
这不是个问题
这个问题分类似乎错了
这个不是我熟悉的地区Java中内部类到底有什么用?
Java中内部类到底有什么用?
java中内部类种类较多,语法比较复杂,用法也不尽相同。
概括下来,可以分类为以下五种内部类。
嵌套内部类
局部内部类
接口内部类
匿名内部类
本篇文章只对实际项目开发中用的较多的,普通内部类与匿名内部类做一定介绍。其他三种若有兴趣请自行通过谷歌或书籍进行了解。
首先通过一个简单的小示例,来看看内部类的语法吧。
import java.util.HashM
public class Parcell {
private HashMap&String, String& testMap = new HashMap&String, String&();
class Contents {
// 返回一个外部类的引用.
public Parcell ParcellRef = Parcell.
class Destination {
public void putSomethingInMap() {
testMap.put("hello", "world");
System.out.println(testMap.get("hello"));
public Destination to() {
return new Destination();
public Contents contents() {
return new Contents();
public void ship(String dest) {
Contents c = new Contents();
Destination d = new Destination();
public static void main(String[] args) {
Parcell p = new Parcell();
Parcell.Contents c = p.contents();
Parcell.Destination d = p.to();
d.putSomethingInMap();
Parcell.Contents c1 = p.new Contents();
内部类的语法和相信大家都很熟悉。
在这里我再自作主张的为大家概括一下
普通内部类持有一个指向外部类的引用。要创建普通内部类,一定要先创建外部类。
普通内部类就像人体的心脏一样,能够随意访问外部类的任意成员变量。
在内部类中可以通过“外部类类名.this”的方式返回一个指向外部类实例的引用.如Parcell.this
在外部类的static方法中若要创建内部类对象,则需要通过“外部类类名.new XXX()”的方式来创建。
普通内部类中不能拥有静态成员变量。静态内部类中可以拥有静态成员变量。也可以拥有非静态成员变量。但是静态内部类不能访问外部类中非静态的成员变量。而普通内部类可以访问外部类的静态成员变量。
为什么static方法中需要p.new XXX()的方式而非static方法中我们直接new 内部类名 就可以创建一个对象了呢?
如果你有这样的疑问请再看看第一条,一定可以想明白的。
普通内部类的语法大致就是这样了。
那么,回到我们主题。
内部类到底有什么用?我们在实际项目中,应该如何使用内部类呢?
内部类的用处或者说用法,归根结底,主要就是一点:
“内部类,主要是设计出来用来解决java中所‘缺少’的,多重继承的概念的。”
什么?难道java不是靠接口来实现多重继承的吗?我认为,这种说法对,也不对。下面我们来看这样一个例子。
你正在参与一项代号X的星际飞船项目。
宇航局的人希望飞船上的综合机器人能够完成两个工作。一是作为向导,能够供人们查阅信息。二是作为修理机器人,完成一些简单的飞船日常维护工作。
作为软件工程师,你被要求编写一段代码来实现这两个功能。
好消息是,向导部分的功能与飞船修理维护的功能,已经由你的同事们完成了!太好了,我只需要调用他们提供给我们的接口就大功告成了!
坏消息是,同事们编写的向导功能与飞船修理功能的接口,竟然都叫做work!
这可伤脑筋了,应该怎么办呢?
public class Guider {
public void work(String name) {
System.out.println("欢迎光临" + name + ",请查阅飞船信息");
-------------------------------------------------------------------
public class Repairer {
public void work (String name) {
System.out.println("你好" + name + ",开始准备对飞船进行维护.");
-------------------------------------------------------------------
public class SpacecraftRobot extends Guider {
public void doGuidWork(String name) {
// 调用guider的work方法
work(name);
public void doRepairWork(String name) {
// 返回内部类引用,调用内部类实例的work方法。
new repairerRobot().doRepairWork(name);
public class repairerRobot extends Repairer {
public void doRepairWork(String name) {
work(name);
太棒了。通过使用内部类与“多重继承”,我们实现了这个功能。现在这个综合机器人能够正常工作了!
对于用户来说,只需要走到机器人面前,告诉机器人你想要doGuidWork还是doRepairWork,它就能够帮你干活儿了。内部类的代码对用户,对外界彻底隐藏了起来,用户唯一能够获得的信息就是这两个方法而已。
匿名内部类
综合机器人原型机试做成功后,新的工作来了!
我们需要对原型机进行量产。以满足每艘星际飞船的需要。
现在我们要编写一间生产综合机器人的工厂。每当我们访问一次工厂,就能够从工厂中提取出一台崭新的综合机器人。聪明的你想到了用工厂设计模式来解决这个问题!但是由于有了内部类,所以我们的工厂,稍稍显得有点不同
// 机器人工厂接口。通过getSpaceCraftRobot方法对外提供机器人
public interface SpaceCraftRobotFactory {
SpacecraftRobot getSpaceCraftRobot();
-------------------------------------------------------------------
public class ProduceSpaceCraftRobot {
// 再也不用显示的创建工厂类的对象了!
private ProduceSpaceCraftRobot() {
// 通过匿名内部类,创建工厂对象!将工厂封装到了内部。不对外界暴露
public static SpaceCraftRobotFactory produceRobot = new SpaceCraftRobotFactory () {
public SpacecraftRobot getSpaceCraftRobot() {
return new SpacecraftRobot();
-------------------------------------------------------------------
public class Consumer {
public static void main(String[] args) {
// 客户来提取机器人了.
SpacecraftRobot x1 = ProduceSpaceCraftRobot.produceRobot.getSpaceCraftRobot();
x1.doGuidWork("lch");
x1.doRepairWork("lch");
通过创建匿名内部类,我们使传统的工厂设计模式优雅了许多!再也不用在外部编写new xxxFactory()这样丑陋,多余的代码了。
现在的工厂被匿名内部类隐藏了起来。客户只需要关心有没有拿到称心如意的机器人。不应该,不需要关心工厂的名字,也不需要知道工厂是干嘛的。
真棒,你顺利完成了宇航局交给你的任务。
恭喜你,你是这个星球的英雄。
Java中的闭包,闭包与内部类的关系
作为一个程序员,即使你从来没有使用过,你也应该听说过闭包与回调。
要从java,特别是j2ee的方向入手去讲解闭包与回调,会比较困难。
所以我们首先从python来入手,来了解闭包与回调到底是什么。
python是一门优秀的解释性语言。你应该掌握他。
下面我们来看一看,标准的回调,在Python中是什么样子的。
#定义一个返回sum函数的名叫base_sum函数的函数
def base_sum(a,b):
#在base_sum中定义一个sum()函数用来计算base_sum(a,b)的形参之合
def sum():
#返回a+b的值
return a + b
#返回定义的sum函数
return sum
#调用base_sum返回函数sum(),可以理解为返回了一个函数指针
return_method = base_sum(1,2)
#打印出返回的函数对象
print(return_method)
#通过指针回调函数对象,返回a与b的合
print(return_method())
----------
&function base_sum.&locals&.sum at 0x&
对于java程序员来说,在一个函数中定义另外一个函数也许会比较烧脑。
你可以试着这样去理解他:
“首先你需要了解的是,函数也需要占据内存空间,所以函数在内存中也是有地址的。在c语言中,函数名就代表这个函数的地址。
如果你有过c语言的编程经验,你就应该知道在一个函数中,返回一个指针是一件很容易的事情。
所以,对于以上这段python代码,你可以尝试把它理解为:
base_sum()函数中定义了一个指向sum()函数的指针,并且这个指针作为base_sum()的返回值。”
好了,现在我们根据上面的例子,来“定义一下闭包”。
调用外部函数,返回一个持有外部函数变量,参数引用的内部函数对象的程序结构,我们就称它为“闭包”。
遗憾的是,java中没有为我们显示的提供指针供我们操作,也没有提供类似python,javascrpit中的函数定义的语法,那么我们应该如何实现闭包呢?
不妨还是通过综合机器人来解答这个疑问吧。这一次,让我们稍稍修改一下综合机器人的代码如下:
public class SpacecraftRobot extends Guider {
// 外部类的成员变量
public SpacecraftRobot(String name) {
this.name =
public class repairerRobot extends Repairer {
public void doRepairWork() {
// 内部类持有外部类的引用,访问外部类的成员变量name。
work(name);
public void doGuidWork() {
// 调用guider的work方法
work(name);
public void doRepairWork() {
// 返回一个持有外部类变量引用的内部类的对象,然后调用这个对象,实现具体的业务逻辑.
new repairerRobot().doRepairWork();
通过对java内部类的合理利用,我们“模拟”出了一个闭包的程序结构。
该程序通过调用外部类对象,从而返回了一个持有外部类对象变量引用的内部类对象。当我们再次调用内部类对象的某个方法时,我们实现了具体的业务逻辑。
内部类通常用来解决“多重继承”的问题。
当你希望隐藏一个类的实现,减少工程中.java文件数量,或者这个类不想被扩展时,你可以通过匿名内部类来创建一个类的对象。
java虽然无法直接在语法层面上支持闭包,但是可以通过内部类来模拟一个闭包的程序结构。
给大家添麻烦了
https://github.com/mikumikulch
https://www.gitbook.com/book/mikumikulch/chucklin_blog/details
Java 基础思维导图,让 Java 不再难懂 - 工具资源 - 掘金思维导图的好处 最近看了一些文章的思维导图,发现思维导图真是个强大的工具。了解了思维导图的作用之后,觉得把它运用到java上应该是个不错的想法,这样回顾知识点的时候一目了然,快速知道自己的短板。 思维导图...
百战程序员_ Java1573题 QQ群:034603 掌握80%年薪20万掌握50%年薪10万 全程项目穿插, 从易到难,含17个项目视频和资料持续更新,请关注www.itbaizhan.com 国内最牛七星级团队马士兵、高淇等11位十年开发经验专...
前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程语言 用于现代多平台应用 100%可与Java(TM)和Android(TM)互操作,它是[JetBrains]开发的基于JVM的语言开发IDE : Intellij / ...
1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语法,集合的语法,io的语法,虚拟机方面的语法。 1、一个&.java&源文件中是否可以包括多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个publ...
用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金Cover 有什么料? 从这篇文章中你能获得这些料: 知道setContentView()之后发生了什么? ... Android 获取 View 宽高的常用正确方式,避免为零 - 掘金相信有很多朋友...
今天早上,上海的地铁八号线又故障了。这是本周第二次遇到地铁故障。 周一早上的时候十一号线故障,不过好在故障比较小,我换乘的时候多等了一列车就顺利赶到公司了。今天早上八号线直接不让进站,到了地铁站以后发现进不去,好多人赶紧骑着共享单车去附近其他线路的地铁站、公交车站。 作为赶...
关于我们的故事,我从不提起 这并不代表,我不爱你 你看——太阳都升起来了 那是我为你种下的一颗痣 ——
在《我们的十年,啊》里,我提到我的爷爷,自我爷爷去世后十年里我仅梦见过一回,我说曾经无法想象的和以为无法接受失去亲人的那颗心也在时间的冲刷下变得越来越硬。在文中我小结到:不是十年让你去接受了,而是十年时间里,你不知不觉的就背叛了曾经那个自己。这样的我们不值得宽恕。 今天新闻...
1. 写文字久了,感动于为数不少的几个铁粉朋友给我的鼓励。后台纷纷收到朋友的夸赞留言,让我有了写下去的信心,无形中也增加了一些压力。 真的怕辜负了朋友们的期待,怕自己的文字越写越烂。总想打开自己的思路,勇敢地突破自己,也怕自己阅历太浅。新的一年还是多读书吧,增加“含金量”,...}

我要回帖

更多关于 java内部类实例化 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信