内部类和匿名内部类

内部类:一个类定义在另一个类里面

1 public class A {
2
3     public class B{
4
5     }
6 }

在这里,B就是一个内部类,A是其相应的外部类。

  1、B可以使用A中的成员变量和函数,但并不代表拥有它们,与继承不同。

  2、编译后生成B$A.class的类。

  3、可以将内部类声明为static。一个static内部类可以使用外部类的名字访问。一个static类是不能访问外部类的非静态成员的。

  4、内部类对象的生成:

非静态:

OuterClass.InnerClass innerObject = OutObject.new Innerclass()  

静态:

OuterClass.InnerClass innerObject = new OutObject.Innerclass()   

匿名内部类:没有名字的内部类。

B b = new B();
b.fun(new A(){
    public void print(){
        System.out.println("匿名内部类");
    }
});

  1、匿名内部类必须扩展父类或实现接口。

  2、匿名内部类编译为名为OuterClassName$n.class的类。如,如果外部类Test有两个匿名类,那么它们就编译成Test$1.class和Test$2.class。

  3、当所在的方法的形参需要被内部类里面使用时,该形参必须为final。

  public Inner getInner(final String name, String city) {
        return new Inner() {
            private String nameStr = name; 

            public String getName() {
                return nameStr;
            }
        };
    }

为什么要定义为final呢?网上有类似解释:

“这是一个编译器设计的问题,如果你了解java的编译原理的话很容易理解。

首先,内部类被编译的时候会生成一个单独的内部类的.class文件,这个文件并不与外部类在同一class文件中。

当外部类传的参数被内部类调用时,从java程序的角度来看是直接的调用例如:

public void dosome(final String a,final int b){

class Dosome{public void dosome(){System.out.println(a+b)}};

Dosome some=new Dosome();

some.dosome();

}

从代码来看好像是那个内部类直接调用的a参数和b参数,但是实际上不是,在java编译器编译以后实际的操作代码是

class Outer$Dosome{

public Dosome(final String a,final int b){

this.Dosome$a=a;

this.Dosome$b=b;

}

public void dosome(){

System.out.println(this.Dosome$a+this.Dosome$b);

}

}}

从以上代码看来,内部类并不是直接调用方法传进来的参数,而是内部类将传进来的参数通过自己的构造器备份到了自己的内部,自己内部的方法调用的实际是自己的属性而不是外部类方法的参数。

这样理解就很容易得出为什么要用final了,因为两者从外表看起来是同一个东西,实际上却不是这样,如果内部类改掉了这些参数的值也不可能影响到原参数,然而这样却失去了参数的一致性,因为从编程人员的角度来看他们是同一个东西,如果编程人员在程序设计的时候在内部类中改掉参数的值,但是外部调用的时候又发现值其实没有被改掉,这就让人非常的难以理解和接受,为了避免这种尴尬的问题存在,所以编译器设计人员把内部类能够使用的参数设定为必须是final来规避这种莫名其妙错误的存在。”

  4、Thread类的匿名内部类实现

public class Demo {
    public static void main(String[] args) {
        Thread t = new Thread() {
            public void run() {
                for (int i = 1; i <= 5; i++) {
                    System.out.print(i + " ");
                }
            }
        };
        t.start();
    }
}运行结果:1 2 3 4 5

  5、Runnable接口的匿名内部类实现

public class Demo {
    public static void main(String[] args) {
        Runnable r = new Runnable() {
            public void run() {
                for (int i = 1; i <= 5; i++) {
                    System.out.print(i + " ");
                }
            }
        };
        Thread t = new Thread(r);
        t.start();
    }
}运行结果:1 2 3 4 5
时间: 2024-08-06 20:02:51

内部类和匿名内部类的相关文章

Java内部类:匿名内部类(四)

Java内部类分为4个部分进行阐述,分别为概览.成员内部类.局部内部类和匿名内部类. 在本文中是Java内部类的匿名内部类,主要讲述匿名内部类的概念.匿名内部类的好处.匿名内部类的使用前提.和匿名内部类的应用场景. 1.匿名内部类的概念 没有类名的类就称作为匿名内部类 2.匿名内部类的好处 简化书写 3.匿名内部类的使用前提 必须存在继承或者实现关系才能使用 4.匿名内部类的应用场景 匿名内部类一般是用于实参 示例代码: package com.rk.innerclass; public cla

19、局部内部类和匿名内部类

package com.lei.duixiang; /** * 局部内部类 * 1.如果需要在方法中使用局部变量,该局部变量需要被设置为 final 类型 * 2.换句话说,在方法中定义的内部类只能访问方法中 final 类型的局部变量 * 这是因为在方法中定义的局部变量相当于一个常量,它的生命周期超出方法运行的生命周期 * 由于该局部变量被设置为final,所以不能在内部类中改变局部变量的值 * @author Administrator * * 匿名内部类 OutClass4 */ inte

内部类 和匿名内部类的基本应用

自己的笔记: 内部的访问规则: 内部类可以直接访问外部类的成员,包括私有. 外部类要想访问内部类,必须建立对象. 之所以可以直接访问外部类的成员,因为内部类持有外部类的引用,格式:Outer.this.x 访问格式: 在内部类定义在外部类中的成员位置上,而且是非私有,可以在外部的其他类中. 可以直接建立内部类的对象. 格式:1. 外部类.内部类 变量名 = 外部对象.内部对象; Outer.Inner in = new Outer().new Inner(); 2. 当内部类在成员位置上,就可以

Java内部类详解--成员内部类,局部内部类,匿名内部类,静态内部类

说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法.今天我们就来一探究竟.下面是本文的目录大纲: 一.内部类基础 二.深入理解内部类 三.内部类的使用场景和好处 四.常见的与内部类相关的笔试面试题 若有不正之处,请多谅解并欢迎批评指正. 请尊重作者劳动成果,转载请标明原文链接: http://www.cnblogs.com/dolphin0520/p/3811445.html 一

Java中的内部类(成员内部类、静态内部类、局部内部类、匿名内部类)

Java中的内部类(成员内部类.静态内部类.局部内部类.匿名内部类) 神话丿小王子的博客主页 我们先看这样一段话:人是由大脑.肢体.器官等身体结果组成.而组成我们人体的心脏它也有自己的属性和行为(血液.跳动),显然,此处不能单方面用属性或者方法表示一个心脏了,而需要一个类,但是这个类要依赖于人这个类存在(因为心脏不能脱离人体而存活,当然不考虑现今社会的发达科技,只从正常情况下来说),所心脏以需要写在人类的内部.内部类就相当于其中的某个器官之一. 首先看看什么是内部类:在类的内部定义另一个类.没错

黑马程序员-----内部类、匿名内部类应用

class Outer{ // 定义外部类private String info = "helloworld" ; // 定义外部类属性private static String info2 = "helloeclipse"; // 定义静态变量class Inner{ // 定义内部类public void print(){// 内部类的好处之一:直接访问外部类属性System.out.println(info) ; // 直接访问外部类属性}}static cl

java面对对象(六)--内部类、匿名内部类

内部类 可以在一个类的内部定义另一个类这种类成为内部类或嵌套类,比如: 1 class Outer{ 2 - 3 class Inner{ 4 -. 5 } 6 } 7 class Outer1{} // 这个Inner1不是Outer1的内部类,不在Outer1的类体括号内 8 class Innter1{ 9 -- 10 } 11 Class Outer2{ //Inner2虽然是在Outer2的方法内,但还是在Outer2的类体括号内,是内部类 12 -- 13 public void t

Java之局部内部类和匿名内部类的区别详解(附源码)

前言 前面提到过,可以在代码块里创建内部类,典型的方式是在一个方法体里面创建.局部内部类不能有访问说明符,因为它不是外围类的一部分:但是他可以访问当前代码块内的常量,以及此外围类的所有成员.下面的例子对局部内部类与匿名内部类的创建进行了比较. 示例源码 package com.mufeng.thetenthchapter; interface Counter { int next(); } public class LocalInnerClass { private int count = 0;

局部内部类和匿名内部类的对比

创建内部类的典型的方式是在一个方法体的里面创建,局部内部类不能有访问说明符,因为它不是外围类的一部分,但是它可以访问当前代码块内的常量,以及此外围类的所有成员.下面的例子对局部内部类与匿名内部类的创建进行了比较. 具体代码实现: 1 package thinking.in.java.demo; 2 3 //定义一个接口 4 interface Counter { 5 int next(); 6 } 7 8 // 主类LocalInnerClass 9 public class LocalInne

面向对象(局部内部类和匿名内部类)

/** * Created by rabbit on 2014-08-05. * 内部类定义在局部时, * 1.不可以被成员修饰符修饰 * 2.可以直接访问外部类中的成员,因为还持有 * 外部类中的引用.但是不可以访问他所在的局部中 * 的变量.只能访问被final修饰的局部变量. * * 匿名内部类 * 1.匿名内部类就是内部类的简写格式 * */ class outer4 {     int x = 3 ;     void method()     {         final int