http://www.cnblogs.com/wenruo/p/5387995.html

内部类 就是在类中嵌套的另一个类。

非静态内部类

创建内部类的方式就是把类定义在外部类里面。

class Out { class In { } }

内部类对于外部类是特殊的,内部类可以访问到外部类的所有成员,包括私有成员。

class Outer {
private String str = "Outer";
class Inner {
public Inner() {str = "Inner";}
}
}

当生成一个内部类对象的时候,它自动和它的外部类有联系,所以要创建内部类对象,必须先有外部类对象。

内部类的类型在外部类除外部类静态方法外不能直接使用内部类的名字,应为OuterClassName.InnerClassName。

内部类可以为私有权限,当内部类为私有时,外部类外对内部类是不可见的。内部类不能有static的域,除非是final的。

创建内部类的方法:

1,外部类方法发返回内部类的引用。

2,通过.new语法实现。

class Outer {
class Inner { } public Inner getInner() {
return new Inner();
}
} public class Test {
public static void main(String args) {
Outer out = new Outer();
Outer.Inner in = out.new Inner();
Outer.Inner in1 = out.getInner();
}
}

在内部类通过OuterClassName.this可以访问外部类对象。

class Outer {
int a = 17;
class Inner {
int a = 3;
public void f() {
System.out.println(this.a + " " + Outer.this.a);
}
}
} public class Test {
public static void main(String[] args) {
Outer out = new Outer();
Outer.Inner in = out.new Inner();
in.f();
}
} // output:3 17

类也可以定义在代码块,包括方法内部。这样类的作用域也就限制在方法内部。此时内部类不能访问外部类,因为它不是外部类的一部分,但是它可以访问当前代码块的常量。

【名字实在是很糟糕

interface Inf {
void f();
} class Outer {
public Inf f() {
class Inner implements Inf {
public void f() {
System.out.println("Inner");
}
}
return new Inner();
}
} public class Test{
public static void main(String[] args) {
Outer out = new Outer();
Inf inf = out.f();
inf.f();
}
}

在这个例子中,通过向上转型为接口类型,完全隐藏了具体实现。

匿名内部类

匿名内部类就是没有名字的内部类aaarticlea/png;base64,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" alt="" />使用样例

interface Contents {
int value();
} public class AnonymousInnerClassTest {
public Contents contents() {
return new Contents() {
private int i = 11;
public int value() { return i; }
};
}
public static void main(String[] args) {
AnonymousInnerClassTest a = new AnonymousInnerClassTest();
Contents c = a.contents();
System.out.println(c.value());
}
}

乍一看很奇怪,但其实很方便的使用方法。在需要使用类的地方直接写一个类的定义。

匿名内部类和在方法中定义类使用功能差不多,区别就是匿名内部类只能产生一个对象。

很容易想到因为匿名类没有名字,而构造器的名字需要和类名一样,所以……它没!有!构!造!器!

如果基类需要有参数的构造器怎么办?只需要在new的时候加上参数就可以了。

public class A {
int i, j;
A(int i, int j) { this.i = i; this.j = j; }
} class B {
public A f(int i, int j) {
return new A(i, j) {
//...
};
}
}

那么如果一个匿名内部类需要构造器来初始化的时候怎么办呢?

在学习类的初始化顺序的时候知道,在构建类对象时是先执行非静态代码段再执行构造器。所以这里可以用代码块带到类似构造器的效果。

class B {
public void print() {}
} public class A {
public B getB() {
return new B() {
{ System.out.println("Inside Instance initialize."); }
public void print() { System.out.println("in anonymous f()"); }
};
} public static void main(String[] args) {
B b = new A().getB();
b.print();
}
}

如果定义一个匿名内部类,并且希望它使用一个在其外部定义的外部对象,那么编译器会要求其参数引用是final的。

Java8中,可以不是final了,但是默认是final的,在内部类不能改变。原因是在内部类,外部变量相当于形参,也就是在内部类改变对外部类无影响,就会造成数据不同步的问题。

interface I {}

public class A {
public static void main(String[] args) {
int x = 0;
new I() {
// x = 3; error
void f() { System.out.println(x); }
};
}
}

Java8中匿名内部类可以用lambda表达式代替,感觉超简洁。语法糖,写代码方便,不过也增加了阅读代码的难度。

interface A1 { void print(); }

class A2 {
public A1 f() {
return () -> { System.out.println("lambda expression."); };
}
} public class Test {
public static void main(String[] args) {
A1 a1 = new A2().f();
a1.print();
}
}

略过略过,以后再学,,,

迭代器实现

interface Iterator {
int next();
boolean hasNext();
} class Sequence {
private int[] items;
private int next = 0;
public int size() {
return items.length;
}
public Sequence(int size) {
items = new int[size];
}
public void add(int x) {
items[next++] = x;
}
public Iterator iterator() {
return new Iterator() {
int i = 0;
public int next() {
return items[i++];
}
public boolean hasNext(){
if (i == next) return false;
return true;
}
};
}
} public class Test {
public static void main(String[] args) {
Sequence s = new Sequence(10);
s.add(1); s.add(3); s.add(5);
Iterator it = s.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}

静态内部类

静态内部类常被称作嵌套类。静态内部类和外部类联系不是很大。

创建静态内部类的对象,并不需要外部类的对象。

不能从嵌套类的对象中访问非静态的外围类对象。

普通的内部类不能有static数据和static字段,也不能包含嵌套类,但是嵌套类可以包含所有这些东西。

class B {
static class C {
}
} public class A {
public static void main(String[] args) {
B.C c = new B.C();
}
}

内部类的继承

既然内部类对象一定要有某个关联外部类对象,那么继承自内部类的子类也一定需要外部类对象。

class WithInner {
public WithInner() {
System.out.println("外部类");
}
class Inner {
public Inner() {
System.out.println("内部类");
}
}
} public class InheritInner extends WithInner.Inner {
InheritInner(WithInner wi) {
wi.super();// 必须使用这样的语法 外部类对象引用+.super
System.out.println("继承自内部类的类");
}
public static void main(String[] args) {
WithInner wi = new WithInner();
InheritInner ii = new InheritInner(wi);
}
} /*
外部类
内部类
继承自内部类的类*/

内部类不能被重写,如下,此时A.Inner 和 B.Inner是毫不相关的两个类。

class A { class Inner {} }
class B extends A { class Inner {} }

继承类的内部类可以继承自基类的内部类 此时不再需要上面继承内部类的构造器

class A {
class B { }
} class A1 extends A {
class B extends A.B { }
}

内部类的名字

每个类都会生成一个.class文件。内部类的名字是:外部类名$内部类名.class,匿名内部类也有名字,外部类名$+一个数字来简单标识。

java 内部类的使用的更多相关文章

  1. Java内部类final语义实现

    本文描述在java内部类中,经常会引用外部类的变量信息.但是这些变量信息是如何传递给内部类的,在表面上并没有相应的线索.本文从字节码层描述在内部类中是如何实现这些语义的. 本地临时变量 基本类型 fi ...

  2. Java内部类详解

    Java内部类详解 说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法.今天我们就 ...

  3. 黑马----JAVA内部类

    黑马程序员:Java培训.Android培训.iOS培训..Net培训 黑马程序员--JAVA内部类 一.内部类分为显式内部类和匿名内部类. 二.显式内部类 1.即显式声明的内部类,它有类名. 2.显 ...

  4. java 内部类 *** 最爱那水货

    注: 转载于http://blog.csdn.net/jiangxinyu/article/details/8177326 Java语言允许在类中再定义类,这种在其它类内部定义的类就叫内部类.内部类又 ...

  5. java内部类和匿名内部类

    内部类即是包含在类里面的又一个类. java内部类分为: 成员内部类.静态嵌套类.方法内部类.匿名内部类 . 内部类的共性 (1).内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.clas ...

  6. Java内部类小程序(成员内部类,静态内部类,匿名内部类)

    /** * 测试java内部类(成员内部类,静态内部类,匿名内部类) * 局部内部类不常用,就不写了. * @package :java05 * @author shaobn * @Describe ...

  7. [转] Java内部类详解

    作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...

  8. java内部类的作用分析

    提起Java内部类(Inner Class)可能很多人不太熟悉,实际上类似的概念在C++里也有,那就是嵌套类(Nested Class),关于这两者的区别与联系,在下文中会有对比.内部类从表面上看,就 ...

  9. 9)Java内部类(Inner Class)

      内部类:不可以有静态数据,静态方法或者又一个静态内部类      内部类的优点:隐藏类的细节,内部类可以声明为私有.内部类可以访问外部类的对象(包括private) 静态内部类:可以有静态数据,静 ...

  10. JAVA内部类(转)

    源出处:JAVA内部类 在java语言中,有一种类叫做内部类(inner class),也称为嵌入类(nested class),它是定义在其他类的内部.内部类作为其外部类的一个成员,与其他成员一样, ...

随机推荐

  1. linux grep命令总结

    风生水起善战者,求之于势,不责于人,故能择人而任势. 博客园    首页    新随笔    联系    订阅    管理 posts - 791,  comments - 394,  trackba ...

  2. HeadFirst设计模式之命令模式

    一. 1.因为是操作经常变化,所以封装操作为command对象.You can do that by introducing “command objects” into your design. A ...

  3. ANDROID_MARS学习笔记_S01_006ImageView

    一.ImageView介绍 设置scalType Must be one of the following constant values. Constant Value Description ma ...

  4. (原创)CityEngine 2014和ArcGIS 10.3冲突问题的解决

      先卸载ArcGIS License Manager 10.3 安装ArcGIS License Manager 10.2.2 用keygen算出ArcGIS 10.3的许可,似乎本许可在ArcGI ...

  5. 分布式事务的管理--atomikos

    在一些业务场景及技术架构下,跨库的事务时不可避免的,这时候如何统一管理事务,保证事务的强一致性是整个系统稳定.可用基石.一些中间件如tuxedo.cics就是凭借这个能力占据了金融.电信.银行等很大的 ...

  6. std::remove

    #include <algorithm> template< class ForwardIt, class T > ForwardIt remove( ForwardIt fi ...

  7. 【HDOJ】4347 The Closest M Points

    居然是KD解. /* 4347 */ #include <iostream> #include <sstream> #include <string> #inclu ...

  8. OM Price Lists

      --select * --from org_organization_definitions; --execute fnd_client_info.set_org_context(111); -- ...

  9. Java之数组array和集合list、set、map

    之前一直分不清楚java中的array,list.同时对set,map,list的用法彻底迷糊,直到看到了这篇文章,讲解的很清楚. 世间上本来没有集合,(只有数组参考C语言)但有人想要,所以有了集合 ...

  10. Hadoop课程介绍

    一.课程简介 1. Hadoop是什么? Apache Hadoop是一款支持数据密集型分布式应用并以Apache 2.0许可协议发布的开源软件框架.它支持在商品硬件构建的大型集群上运行的应用程序.H ...