java匿名内部类底层原理
Java中内部类详解—匿名内部类

Java中内部类详解 —匿名内部类
什么是内部类?
将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。
成员内部类
定义在类中方法外的类。
定义格式:
class 外部类 { class 内部类{ }
}
在描述事物时,若一个事物内部还包含其他事物,就可以使用内部类这种结构。比如,汽车类Car 中包含发动机类Engine ,这时,Engine就可 以使用内部类来描述,定义在成员位置。
}
创建匿名内部类,并调用:
public class InnerDemo { public static void main(String[] args) { /* 1.等号右边:是匿名内部类,定义并创建该接口的子类对象 2.等号左边:是多态赋值,接口类型引用指向子类对象 */ FlyAble f = new FlyAble(){ public void fly() { System.out.println("我飞了~~~"); } };
}
以上两步,也可以简化为一步,代码如下:
public class InnerDemo3 { public static void main(String[] args) { /* 创建匿名内部类,直接传递给showFly(FlyAble f) */ showFly( new FlyAble(){ public void fly() { System.out.println("我飞了~~~"); } }); }
}
定义测试类:
public class InnerDemo { public static void main(String[] args) { // 创建外部类对象 Person p = new Person(); // 创建内部类对象 Heart heart = p.new Heart();
java内部类和匿名类从入门到深入

1 内部类⏹内部类定义:⏹在A类的内部但是所有方法的外部定义了一个B类,则B类就是A类的内部类,A是B的外部类⏹内部类访问原则⏹内部类的方法可以访问外部类所有的成员⏹外部类的方法不可以直接访问内部类的成员⏹内部类的优点:⏹可以让一个类方便的访问另一个类中的所有成员⏹增加程序的安全性,有效避免其他不相关类对该类的访问⏹何时使用内部类⏹如果一个A类要使用B类的所有成员,并且A类不需要被除B类以外的其他类访问,则我们应当把A类定义为B类的内部类⏹class A{⏹private int i = 1;⏹private void f(){⏹}⏹⏹//B是A的内部类⏹class B{⏹public int bi = 10;⏹⏹//非静态的内部类可以访问外部类所有的成员⏹public void g(){⏹System.out.printf("i = %d\n", i);⏹f();⏹}⏹}⏹⏹public void k(){⏹//g(); //error 外部类的方法不可以直接访问内部类的成员⏹//System.out.println(bi); //error 外部类的方法不可以直接访问内部类的成员⏹⏹ B bb = new B();⏹bb.g();⏹}⏹}⏹public class Test{⏹public static void main(String[] args){⏹ A aa = new A();⏹aa.k();⏹}⏹}本程序证明了:•外部类的方法不可以直接访问内部类的成员•内部类的方法却可以访问外部类的所有成员匿名类⏹匿名类是一种特殊的内部类⏹如果在一个方法内部定义了一个匿名类,则该匿名类可以访问⏹外部类的所有成员⏹包裹本匿名类的方法中的所有final类型的局部变量,非fianl类型的局部变量无法被匿名类访问⏹import java.awt.*;⏹import java.awt.event.*;⏹public class TestWindow⏹{⏹public static void main(String[] args)⏹{⏹//如果把10行的final去掉,本程序在18行就会报错,⏹ //因为匿名类只能访问包裹它的方法中的final类型的局部变量⏹final Frame f = new Frame(); //10⏹ f.setSize(200, 200);⏹ f.addWindowListener(⏹new WindowAdapter()⏹{⏹public voidwindowClosing(WindowEvent e)⏹{⏹ f.setVisible(false);//18行⏹System.exit(-1);⏹}⏹}⏹);⏹ f.setVisible(true);⏹}⏹}创建匿名类的三种方式⏹继承父类⏹实现接口⏹实现抽象类创建匿名类之实现接口⏹假设A是接口名new A(){实现接口中方法的代码};⏹功能:⏹生成一个实现了A接口的匿名类创建匿名类之实现抽象类⏹假设A是抽象类⏹格式:⏹new A()⏹{⏹实现了A类的所有抽象类的方法代码⏹添加自己的方法或属性代码【不建议,因为没有实际意义】⏹}⏹功能:⏹生成一个匿名类,该匿名类必须得实现了A类的所有抽象方法,当然该匿名类也可以定义自己的属性和方法创建匿名类之继承父类⏹假设A是个类名⏹格式:⏹new A()⏹{⏹重写了A类的方法代码⏹添加自己的属性和方法【不建议,因为没有实际意义】⏹}⏹生成一个A类的子类对象,该匿名类对象继承了A的所有非private成员class A{private int i = 1;private void f(){System.out.println("哈哈");}//B是A的内部类class B{public int bi = 10;//非静态的内部类可以访问外部类所有的成员public void g(){System.out.printf("i = %d\n", i);f();}}public void k(){//g(); //error 外部类的方法不可以直接访问内部类的成员//System.out.println(bi); //error 外部类的方法不可以直接访问内部类的成员B bb = new B();bb.g();}}public class Test{public static void main(String[] args){A aa = new A();aa.k();}}/*假设A是接口名new A(){实现接口中方法的代码};功能:生成一个实现了A接口的匿名类*/interface It{void f();//void g(); // 如果该语句生效的话,21行到27行的代码中就必须的实现g 方法}public class TestAnonyClass_1{public static void main(String[] args){It it = new It(){ //21行public void f(){System.out.println("哈哈");}}; //27行//error// It it = new It1()// ( //是{ 不是(// public void f()// {// System.out.println("哈哈");// }// ); // 是} 不是)//error// It it = new It()// (// {// public void f()// {// System.out.println("哈哈"); // }// }// ;it.f();}}/*假设A是抽象类new A(){实现了A类的所有抽象类的方法代码添加自己的方法或属性代码【不建议,因为没有实际意义】}功能:生成一个匿名类,该匿名类必须得实现了A类的所有抽象方法,当然该匿名类也可以定义自己的属性和方法*/abstract class A{abstract public void f();public void g(){}}public class TestAnonyClass_2{public static void main(String[] args){A aa = new A(){//f方法不可以被注释掉, 因为f是抽象方法,匿名类必须的实现public void f(){System.out.println("FFFF");}//g方法可以被注释掉public void g(){System.out.println("GGGG");}public void k(){}};aa.f();aa.g();//aa.k();}}/*在JDK 1.6中的运行结果是:-----------------------------FFFFGGGG-----------------------------*//*假设A是个类名new A(){重写了A类的方法代码自己添加的属性和方法【【不建议,因为没有实际意义】】}功能:生成一个A类的子类对象,该匿名类对象继承了A的所有非private成员*/class A{public void f(){System.out.println("哈哈");}}public class TestAnonyClass_3{public static void main(String[] args){A aa = new A(){//重写了父类A的方法public void f(){System.out.println("嘿嘿");}//可以定义自己的方法,但没有任何实际意义public void g(){System.out.println("GGGG");}};aa.f();//aa.g(); //error}}/*在JDK 1.6中的运行结果是:-----------------------------FFFFGGGG-----------------------------*//*2009年6月25日16:14:23文本框内容相加方法一:主函数代码过多程序逻辑混乱不推荐*/import java.awt.*;import java.awt.event.*;public class TestTF_1{public static TextField tf1, tf2, tf3;public static void main(String[] args){Frame f = new Frame();tf1 = new TextField(30);tf2 = new TextField(30);tf3 = new TextField(30);Button bn = new Button("=");Label lb = new Label("+");f.setLayout(new FlowLayout());f.add(tf1);f.add(lb);f.add(tf2);f.add(bn);f.add(tf3);bn.addActionListener(new MyMonitor());f.pack();f.setVisible(true);}}class MyMonitor implements ActionListener{public void actionPerformed(ActionEvent e){int num1 = Integer.parseInt(TestTF_1.tf1.getText());int num2 = Integer.parseInt(TestTF_1.tf2.getText());int num3 = num1 + num2;TestTF_1.tf3.setText(num3+"");}}/*2009年6月25日16:33:20文本框内容相加方法二:通过在B类中定义A类的属性,就可以达到在B类访问A类成员的目的但是通过这种方式无法访问A类私有成员本方式既繁琐又有局限性,不推荐*/import java.awt.*;import java.awt.event.*;public class TestTF_2{public static void main(String[] args){new TF().launch();}}class TF{public TextField tf1, tf2, tf3;public void launch(){Frame f = new Frame();tf1 = new TextField(30);tf2 = new TextField(30);tf3 = new TextField(30);Button bn = new Button("=");Label lb = new Label("+");f.setLayout(new FlowLayout());f.add(tf1);f.add(lb);f.add(tf2);f.add(bn);f.add(tf3);bn.addActionListener(new MyMonitor(this));f.pack();f.setVisible(true);}}class MyMonitor implements ActionListener{public TF tf = null;public MyMonitor(){}public MyMonitor(TF tf){this.tf = tf;}public void actionPerformed(ActionEvent e){int num1 = Integer.parseInt(tf.tf1.getText());int num2 = Integer.parseInt(tf.tf2.getText());int num3 = num1 + num2;tf.tf3.setText(num3 + "");}}/*2009年6月25日16:37:28文本框内容相加方法三:把B当做A的内部类,则我们就可以在B类中轻松访问A类的所有成员,当然包括私有成员推荐*/import java.awt.*;import java.awt.event.*;public class TestTF_3{public static void main(String[] args){new TF().launch();}}class TF{public TextField tf1, tf2, tf3;public void launch(){Frame f = new Frame();tf1 = new TextField(30);tf2 = new TextField(30);tf3 = new TextField(30);Button bn = new Button("=");Label lb = new Label("+");f.setLayout(new FlowLayout());f.add(tf1);f.add(lb);f.add(tf2);f.add(bn);f.add(tf3);bn.addActionListener(new MyMonitor());f.pack();f.setVisible(true);}class MyMonitor implements ActionListener{public void actionPerformed(ActionEvent e){int num1 = Integer.parseInt(tf1.getText());int num2 = Integer.parseInt(tf2.getText());int num3 = num1 + num2;tf3.setText(num3 + "");}}}/*2009年6月25日16:37:28文本框内容相加方法三:把B当做A的内部类,则我们就可以在B类中轻松访问A类的所有成员,当然包括私有成员推荐*/import java.awt.*;import java.awt.event.*;public class TestTF_3{public static void main(String[] args){new TF().launch();}}class TF{public TextField tf1, tf2, tf3;public void launch(){Frame f = new Frame();tf1 = new TextField(30);tf2 = new TextField(30);tf3 = new TextField(30);Button bn = new Button("=");Label lb = new Label("+");f.setLayout(new FlowLayout());f.add(tf1);f.add(lb);f.add(tf2);f.add(bn);f.add(tf3);bn.addActionListener(new MyMonitor());f.pack();f.setVisible(true);}class MyMonitor implements ActionListener{public void actionPerformed(ActionEvent e){int num1 = Integer.parseInt(tf1.getText());int num2 = Integer.parseInt(tf2.getText());int num3 = num1 + num2;tf3.setText(num3 + "");}}}。
java 匿名内部类构造方法

java 匿名内部类构造方法java中的匿名内部类是一种特殊的内部类,在创建对象的同时定义类的实现,并且不需要为其命名。
它常用于需要实现接口或继承抽象类的场景,可以简化代码结构并使代码更加具有灵活性。
本文将详细介绍java匿名内部类的构造方法的用法和原理。
首先,我们需要了解Java中的内部类。
内部类是定义在其他类内部的类,它具有访问外部类的成员变量和方法的能力。
内部类在使用上具有很多优势,例如可以访问外部类的私有成员、可以编写更加清晰的代码结构等。
而匿名内部类是内部类的一种特殊形式,没有命名,直接在创建对象的时候定义类的实现。
在Java中,构造方法是用于初始化对象的特殊方法。
所有的类都至少有一个构造方法,默认情况下,如果我们没有显式地提供构造方法,Java会自动生成一个无参构造方法。
而对于匿名内部类,它也具备构造方法,用于完成对象的初始化工作。
其次,让我们通过一个具体的例子来演示匿名内部类的构造方法的应用。
假设我们有一个接口Animal,并且有一个实现了该接口的类Dog。
接口Animal定义了一个eat()方法,而Dog类实现了该方法,并在内部打印出"Dog is eating"。
现在我们想要创建一个匿名内部类来实现Animal接口,并在eat()方法内部打印出"Anonymous animal is eating"。
我们可以使用如下代码实现:javaAnimal anonymousAnimal = new Animal() {public void eat() {System.out.println("Anonymous animal is eating");}};在上述代码中,我们创建了一个Animal接口的匿名内部类,并实现了其中的eat()方法。
由于没有给这个匿名内部类命名,我们直接将它赋值给了一个Animal类型的变量anonymousAnimal。
匿名类的原理

匿名类的原理匿名类是一种在Java编程语言中使用的特殊类形式。
它包含了一个没有明确声明的类,通常用于定义一些简单的功能。
在Java中,使用匿名类可以方便地创建一个只需临时使用的类,而无需显式地定义独立的类。
本文将以1200字以上的篇幅,详细解析匿名类的原理。
在Java中,匿名类可以用于创建一个实现特定接口或继承特定类的对象。
在使用匿名类时,可以在创建对象的同时定义这个类的内容。
匿名类并没有名字,所以只能创建一个匿名类的对象,无法通过类名再次引用。
匿名类的定义方式通常是在创建对象时,使用new关键字后面紧跟着接口或类名,并定义其内容。
匿名类的原理可以从以下几个方面来解析:1. 匿名类的定义语法:在Java中,匿名类的定义方式是在创建对象时添加一个类或接口的定义。
其语法结构如下:new 类名或接口名(){匿名类的内容}其中,类名或接口名可以是一个类名,也可以是一个接口名。
匿名类的内容可以包括实例变量、方法等。
2. 匿名类的实现方式:匿名类实际上是一个局部类,它在编译时会被编译器自动命名,并生成一个.class 文件。
这个类会继承或实现匿名类创建时指定的类或接口,并可以重写或实现其中的方法。
3. 匿名类的继承与接口实现:匿名类可以继承一个类,也可以实现一个接口。
如果匿名类继承一个类,那么它可以继承该类的全部字段和方法,并可以在匿名类中重写这些方法。
如果匿名类实现一个接口,那么它需要实现接口中的全部方法。
4. 匿名类的使用场景:匿名类通常用于需要创建一个临时对象,或者需要对某个接口或类进行简单的扩展和重写的场景。
它可以使代码更加简洁,并且可以避免定义额外的类。
5. 匿名类的实际应用:匿名类在Java中的应用非常广泛。
在实际开发中,它常用于事件监听器、线程类、回调函数等各种场景。
使用匿名类可以减少代码量,并且使代码更加清晰简洁。
总结起来,匿名类是一种在Java中使用的特殊类形式。
它通过在创建对象的同时定义类的内容,可以方便地创建一个只需临时使用的类。
内部类之匿名内部类

内部类之匿名内部类•内部类标识符:•每个类会产生一个.class文件,文件名即为类名。
同样,内部类也会产生一个.class文件,但是它的名称却不是内部类的类名,而是有着严格限制:外围类的名字,加上$,再加上内部类名字•匿名内部类•也就是没有名字的内部类,其名称由Java编译器给出,一般是形如:外部类名称$ 匿名类顺序,没有名称也就是其他地方就不能引用,不能实例化,只用一次,当然也就不能有构造器。
它通常用来简化代码编写•匿名内部的创建格式:new 父类构造器(参数列表)|实现接口(){//匿名内部类的类体部分}•匿名类分类•匿名类由于是一个new的结果,所以其实可以赋值给一个父类对象。
因此可以分为两种匿名类,成员匿名类和局部匿名类(作为函数参数)。
•使用匿名内部类前提条件•必须继承一个父类或实现一个接口当然也仅能只继承一个父类或者实现接口。
同时它也是没有class关键字,这是因为匿名内部类是直接使用new来生成一个对象的引用。
当然这个引用是隐式•匿名内部类使用的注意事项•1、使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。
同时要实现父类或接口中所有抽象方法,可以改写父类中的方法,添加自定义方法。
•2、匿名内部类因为没有类名,可知匿名内部类中是不能定义构造函数的。
•3、匿名内部类中不能存在任何的静态成员变量和静态方法。
•4、匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内类生效。
•5、因为在创建匿名内部类的时候,会立即创建它的实例,匿名内部类不能是抽象的,它必须要实现继承的类或者实现接口的类的所有抽象方法。
•6、匿名内部类和外部类有同名变量方法)时,默认访问的是匿名内部类的变量(方法),要访问外部类的变量(方法)则需要加上外部类的类名。
匿名内部类访问外部类成员变量或成员方法必须用static修饰•匿名内部类的使用package com.vg.demo04;//不使用匿名内部类来实现抽象方法abstract class Person{public abstract void eat();}class Child extends Person{public void eat() {System.out.println("eat something");}}public class TestDemoniming {public static void main(String[] args) {Person p = new Child();p.eat();}}package com.vg.demo04;//匿名内部类的基本实现abstract class Person{public abstract void eat();}public class TestDemoniming {public static void main(String[] args) { Person p = new Person() {public void eat() {System.out.println("eat something"); }};p.eat();}}package com.vg.demo04;//在接口上使用匿名内部类interface Person{public abstract void eat();}public class TestDemoniming {public static void main(String[] args) { Person p = new Person() {public void eat() {System.out.println("eat something"); }};p.eat();}}package com.vg.demo04;//Thread类的匿名内部类实现public class TestDemoniming {public static void main(String[] args) { Thread t = new Thread() {public void run () {for(int i = 1;i<=5;i ) {System.out.println(i " ");}}};t.start();}}package com.vg.demo04;//Runnable接口的匿名内部类实现public class TestDemoniming {public static void main(String[] args) { Runnable r = new Runnable() { public void run () {for(int i = 1;i<=5;i ) {System.out.println(i " ");}}};Thread t = new Thread(r);t.start();}}来源:。
java-内部类与匿名内部类

java-内部类与匿名内部类内部类:类名、抽象类名、接⼝作为形参和返回值1.类名作为形参和返回值:⽅法的形参是类名,其实需要的是该类的对象⽅法的返回值是类名,其实返回的是该类的对象public class Cat {public void eat(){System.out.println("猫吃鱼");}}class CatOperator{public void useCat(Cat c){ //Cat c=new Cat();c.eat();}public Cat getCat(){Cat c = new Cat();return c;}}//测试类class test07{public static void main(String[] args) {CatOperator co = new CatOperator();Cat c =new Cat();//⽅法的形参是类名,其实需要的是该类的对象eCat(c);//⽅法的返回值是类名,其实返回的是该类的对象co.getCat().eat();}}2.抽象类名作为形参和返回值⽅法的形参是抽象 类名,其实需要的是该抽象类的⼦类对象⽅法的返回值是类名,其实返回的是该抽象类的⼦类对象public abstract class Animal {public abstract void eat();}public class AnimalOperator{public void useAnimal(Animal a){ //Animal a = new Rabbit();a.eat();}public Animal getAnimal(){Animal r = new Rabbit();return r;}}//测试类public class AnimalTest{public static void main(String[] args) {AnimalOperator ao =new AnimalOperator();Animal rabbit = new Rabbit();//⽅法的形参是抽象类名,其实需要的是该抽象类的⼦类对象eAnimal(rabbit);//⽅法的返回值是类名,其实返回的是该抽象类的⼦类对象ao.getAnimal().eat();}}3.接⼝名作为形参和返回值⽅法的形参是接⼝名,其实需要的是该接⼝的实现类对象⽅法的返回值是接⼝名,其实返回的是该接⼝的实现类对象public interface Jumping {//抽象⽅法void jump();}public class JumpingOperator {public void useJumping(Jumping j){ // Jumping j=new Dog();j.jump();}public Jumping getJumping(){Jumping j = new Dog();return j;}}public class Dog implements Jumping{public void jump() {System.out.println("狗可以跳⾼");}}//测试类public class JumpingTest {public static void main(String[] args) {//创建操作类对象并调⽤⽅法JumpingOperator jo = new JumpingOperator();Jumping j =new Dog();//⽅法的形参是接⼝名,其实需要的是该接⼝的实现类对象eJumping(j);//⽅法的返回值是接⼝名,其实返回的是该接⼝的实现类对象Jumping j2 = jo.getJumping();j2.jump();}}内部类:内部类概述:就是在⼀个类中定义⼀个类,举例:在⼀个类A的内部定义⼀个类B,类B就称为内部类格式:public class 类名{修饰符 class 类名{}}内部类的访问特点:1)内部类可以直接访问外部类的成员,包括private2)外部类要访问内部类的成员,必须创建对象内部类的分类:按照内部类在类中定义位置的不同,可以分为如下2种形式1)在类的成员位置:成员内部类2)在类的局部位置:局部内部类成员内部类,创建使⽤://内部类为publicpublic class Outer {private int number=10;public class Inner{public void show(){System.out.println(number);}}public void method(){Inner i = new Inner();i.show();}}class test08{public static void main(String[] args) {//创建内部类对象Outer.Inner inner = new Outer().new Inner();inner.show();}}//内部类为privatepublic class Outer {private int number=10;private class Inner{public void show(){System.out.println(number);}}public void method(){Inner i = new Inner();i.show();}}class test08{public static void main(String[] args) {//创建内部类对象Outer o = new Outer();o.method();}}局部内部类:局部内部类是在⽅法中定义的类,所以外界是⽆法直接使⽤,需要在⽅法内部创建对象并使⽤该类可以直接访问外部类的成员,也可以访问内部类的局部变量public class Outer1 {private int num=20;public void method(){class Inner1{public void show(){int num2 =30;//局部内部类访问外部类的成员System.out.println(num);System.out.println(num2);}}//⽅法内部创建局部内部类对象,才可使⽤局部内部类对象 Inner1 i =new Inner1();i.show();}}class OutTest{public static void main(String[] args) {Outer1 o1 = new Outer1();o1.method();}}匿名内部类(为局部内部类的⼀种特殊形式)本质:是⼀个继承了该类或者实现了该接⼝的⼦类匿名对象前提:存在⼀个类或者接⼝,这⾥的类可以是具体类也可以是抽象类new 类名或者接⼝名(){重写⽅法;}public class Outer2 {public void method(){//是⼀个继承了该类或者实现了该接⼝的⼦类匿名对象new Inter(){public void show() {System.out.println("匿名内部类");}}.show();}}class test10{public static void main(String[] args) {Outer2 o2 = new Outer2();o2.method();}}匿名内部类的多次调⽤ublic class Outer2 {public void method(){//是⼀个继承了该类或者实现了该接⼝的⼦类匿名对象Inter i =new Inter(){public void show() {System.out.println("匿名内部类");}};//实现匿名内部类的多次调⽤i.show();i.show();}}class test10{public static void main(String[] args) {Outer2 o2 = new Outer2();o2.method();}}匿名内部类在开发中的使⽤public interface Jumping {//抽象⽅法void jump();}public class JumpingOperator {public void useJumping(Jumping j){ // Jumping j=new Dog();j.jump();}}public class Dog implements Jumping{public void jump() {System.out.println("狗可以跳⾼");}}public class JumpingTest {public static void main(String[] args) {//创建操作类对象并调⽤⽅法JumpingOperator jo = new JumpingOperator();Jumping j =new Dog(); //不使⽤匿名内部类,创建类猫狗兔⼦实现 Jumping接⼝的⽅式eJumping(j);System.out.println("----------");//运⽤匿名内部类不需要在⾛创建类猫狗兔⼦实现 Jumping接⼝了,如果有猫狗兔⼦....要实现跳⾼直接⽤下⾯的⽅式编写 //匿名内部类本质:⼀个继承了该类或者实现了该接⼝的⼦类匿名对象eJumping(new Jumping() {public void jump() {System.out.println("猫可以跳⾼了1111");}});eJumping(new Jumping() {public void jump() {System.out.println("狗可以跳⾼了1111");}});}}。
Java的内部类和匿名类剖析

Java的内部类和匿名类剖析Java 1.1通过对Java语言规范进行修改,显着简化了一些实用结构的实现。
在那些修改中,最引人注目的就是内部类和匿名类。
如运用得当,它们可使程序更易理解和维护。
本文介绍内部类和匿名类在Java代码中是如何具体工作的,如何正确使用它们,以及如何避免一些常见的错误。
下面来看看这些特性具体是如何工作的?1、非静态内部类如果内部类没有指定static修饰符,就拥有对外部类的所有成员的完全访问权限,包括实例字段和方法。
为实现这一行为,非静态内部类存储着对外部类的实例的一个隐式引用。
所以,对一个非静态内部类进行实例化需要采用不同语法的new语句:2、引用内部类内部类最自然的一种应用就是声明只在另一个类的内部使用的类,或者声明与另一个类密切相关的类。
如清单B所示,它是一个链表的简单实现。
由于Node类通常只在LinkedList 的范围内使用,所以最好将Node声明为LinkedList的一个内部类。
适用于类成员的访问控制修改符也适用于内部类;也就是说,内部类可以具有package、protected、private和public 访问权限,它们的语义和正常的语义没有什么不同。
由于Node要在LinkedList的外部使用,所以把它声明为public.然而,修饰符static具有不同的含义。
应用于内部类时,它声明的类具有与其他类相同的语义,也就是可进行实例化,并像一个标准类那样使用。
惟一的区别就是它拥有对外部类的所有静态成员的完全访问权限。
清单C展示了一个简单的程序,它创建一个链表,并将它打印到标准输出设备。
3、更优化的代码内部和匿名类是Java 1.1为我们提供的两个出色的工具。
它们提供了更好的封装,结果就是使代码更容易理解和维护,使相关的类都能存在于同一个源代码文件中(这要归功于内部类),并能避免一个程序产生大量非常小的类(这要归功于匿名类)。
4、new这种形式的new语句要求外部类的一个实例,使内部类能在那个实例的上下文中创建。
Java:匿名类,匿名内部类

Java:匿名类,匿名内部类内部类匿名类⾸发⽇期:2018-03-25内部类:在⼀个类中定义另⼀个类,这样定义的类称为内部类。
【包含内部类的类可以称为内部类的外部类】如果想要通过⼀个类来使⽤另⼀个类,可以定义为内部类。
【⽐如苹果⼿机类,苹果⼿机类中的黄⾦版的是特别定制的】内部类的外部类的成员变量在内部类中仍然有效,内部类中的⽅法也可以调⽤外部类中的⽅法。
【不论是静态还是⾮静态的,内部类都可以直接调⽤外部类中的属性,】内部类的类体中不可以声明类变量和类⽅法。
内部类可以由外部类使⽤外部类中在函数中创建内部类对象来使⽤,,如果内部类的权限是⾮私有,⾮静态的,就可以在外部其他程序中被访问到,就可以通过创建外部类对象完成,;如果内部类是静态的,⾮私有的,静态成员可以直接类名调⽤,⾮静态成员通过创建外部类对象使⽤。
class Outer{int a=5;static int b=6;void show() {System.out.println("hello world");}class Inner{void use() {System.out.println(a);//5System.out.println(b);//6show();//hello world}}void create() {new Inner().use();}}public class Demo {public static void main(String[] args) {new Outer().create();Outer.Inner oi=new Outer().new Inner();e();}}补充:内部类的字节码⽂件会不⼀样。
会变成外部类名$内部类名将内部类定义在了局部位置上。
可以访问外部类的所有成员局部内部类不能访问所在局部的局部变量(本来他们⽣命周期不同,本来内部类对象的空间没有消失,对象⽣命长)若需访问,加final修饰变量即可,加final变成常量。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
java匿名内部类底层原理
Java匿名内部类是Java编程语言中的一个特性,允许你在一个方法内部定义一个没有名字的类。
这种类被称为匿名内部类。
匿名内部类的底层原理主要涉及到Java的字节码和内存模型。
下面是一些关键的概念和步骤:
1. 字节码:Java源代码在编译时会被转换成字节码。
字节码是一种平台无关的中间代码,可以在任何安装了Java虚拟机(JVM)的设备上运行。
2. 内存模型:当你在Java中创建对象时,JVM会在堆内存中为这个对象分配空间。
每个对象都包含类信息(即类的元数据)、实例变量和一些用于跟踪和管理的额外信息。
3. 匿名内部类的生成:当你在代码中定义一个匿名内部类时,JVM会做以下几件事情:
字节码生成:编译器会将匿名内部类的定义转换成字节码。
由于这个类没有名字,编译器会为它生成一个独特的类名,通常是基于它所在的方法和代码的位置。
堆内存分配:JVM会在堆内存中为这个匿名内部类对象分配空间。
这个对象会包含这个匿名类的所有实例变量和任何实现的方法。
实例化:当你在代码中创建这个匿名内部类的实例时,JVM会在堆内存中为这个新对象分配空间,并调用其构造函数来初始化这个对象。
4. 垃圾收集:当一个对象不再被引用时,JVM的垃圾收集器会回收这个对象占用的内存。
对于匿名内部类,如果它是局部变量并且它的范围已经结束(例如,方法已经返回),那么这个匿名类的对象和它占用的内存可能会被回收。
需要注意的是,由于JVM的内存管理策略和垃圾收集机制,实际的行为可能会因JVM的实现和运行时的环境而有所不同。