-
2021-06-01 19:44:59
什么是局部内部类?
定义在方法中的内部类。
注意:
1、内部类不能被public、private、static修饰;
2、在外部类中不能创建内部类的实例;
3、创建内部类的实例只能在包含他的方法中;
4、内部类访问包含他的方法中的变量必须有final修饰;
5、外部类不能访问局部内部类,只能在方法体中访问局部内部类,且访问必须在内部类定义之后。
代码:
public class Outer { private String s1 = "this is s1 in Outer"; private String s_outer = "this is s_outer in Outer"; private String method1() { return "this is method1 in Outer"; } private String method2() { return "this is method2 in Outer"; } public void method3() { final String s_method = "this is s_method in method3"; class Inner { private String s1 = "this is s1 in Inner"; public void method1() { // 内部类访问外部方法的变量,需要有final修饰 System.out.println(s_method); // 局部内部类可直接访问外部类的变量,即使是私有的 System.out.println(s_outer); // 内部类和外部类有同名变量和方法时 System.out.println(s1); System.out.println(Outer.this.s1); System.out.println(method2()); System.out.println(Outer.this.method2()); } private String method2() { return "this is method2 in Inner"; } } Inner inner = new Inner(); inner.method1(); } }
调用:
public class MainClass { public static void main(String[] args) { Outer outer = new Outer(); outer.method3(); } }
打印:
this is s_method in method3 this is s_outer in Outer this is s1 in Inner this is s1 in Outer this is method2 in Inner this is method2 in Outer
分析:
反编译后自动生成文件:Outer$1Inner.class
Outer 反编译代码1:
public class jichu.Outer { private java.lang.String s1; private java.lang.String s_outer; public jichu.Outer(); private java.lang.String method1(); private java.lang.String method2(); public void method3(); static java.lang.String access$0(jichu.Outer); static java.lang.String access$1(jichu.Outer); static java.lang.String access$2(jichu.Outer); }
Outer 反编译代码2:
public class Outer { private String s1 = "this is s1 in Outer"; private String s_outer = "this is s_outer in Outer"; private String method1() { return "this is method1 in Outer"; } private String method2() { return "this is method2 in Outer"; } public void method3() { String s_method = "this is s_method in method3"; Object inner = new Object() { private String s1 = "this is s1 in Inner"; public void method1() { System.out.println("this is s_method in method3"); System.out.println(Outer.this.s_outer); System.out.println(this.s1); System.out.println(Outer.this.s1); System.out.println(method2()); System.out.println(Outer.this.method2()); } private String method2() { return "this is method2 in Inner"; } }; inner.method1(); } }
Outer$1Inner反编译代码1:
class jichu.Outer$1Inner { private java.lang.String s1; final jichu.Outer this$0; jichu.Outer$1Inner(jichu.Outer); public void method1(); private java.lang.String method2(); }
Outer$1Inner反编译代码2:
class Outer$1Inner { private String s1 = "this is s1 in Inner"; Outer$1Inner(Outer paramOuter) {} public void method1() { System.out.println("this is s_method in method3"); System.out.println(Outer.access$0(this.this$0)); System.out.println(this.s1); System.out.println(Outer.access$1(this.this$0)); System.out.println(method2()); System.out.println(Outer.access$2(this.this$0)); } private String method2() { return "this is method2 in Inner"; } }
Outer$1Inner反编译代码1中有:
final jichu.Outer this$0; jichu.Outer$1Inner(jichu.Outer);
Outer 反编译代码1中有:
static java.lang.String access$0(jichu.Outer); static java.lang.String access$1(jichu.Outer); static java.lang.String access$2(jichu.Outer);
可知局部内部类可随意访问外部类的成员变量和方法,即使是私有的。(在成员内部类反编译中也有同样的代码,详见成员内部类详解)
内部类和外部类有同名变量和方法时,需要通过Outer.this方式来访问外部类成员变量或方法。
总结
1、内部类不能被public、private、static修饰;
2、在外部类中不能创建内部类的实例;
3、创建内部类的实例只能在包含他的方法中;
4、内部类访问包含他的方法中的变量必须有final修饰;
5、外部类不能访问局部内部类,只能在方法体中访问局部内部类,且访问必须在内部类定义之后。
6、可知局部内部类可随意访问外部类的成员变量和方法,即使是私有的。
7、内部类和外部类有同名变量和方法时,需要通过Outer.this方式来访问外部类成员变量或方法。
转自:https://www.cnblogs.com/SQP51312/p/6108848.html
更多相关内容 -
详细分析Java内部类——局部内部类
2020-08-24 20:20:56主要介绍了Java局部内部类的相关资料,帮助大家更好的理解和学习Java 内部类的知识,感兴趣的朋友可以了解下 -
Java局部内部类原理与用法实例分析
2020-08-25 14:09:35主要介绍了Java局部内部类原理与用法,结合实例形式分析了Java局部内部类功能、用法及相关操作注意事项,需要的朋友可以参考下 -
Java基础 - 内部类02 - 局部内部类详解
2022-02-04 20:42:121.什么是局部内部类 定义 : 局部内部类是定义在外部类的局部位置,且一定要有类名; 局部内部类的本质仍然是一个类。 2.局部内部类的特性(关键) * 1. 可以直接访问 外部类 的所有成员,包括 私有的; * 2. ...1.什么是局部内部类
定义 : 局部内部类是定义在外部类的局部位置,且一定要有类名;
局部内部类的本质仍然是一个类。
2.局部内部类的特性(关键)
* 1. 可以直接访问 外部类 的所有成员,包括 私有的; * 2. 局部内部类 的地位相当于一个局部变量,因此不能添加访问修饰符, * 但可以使用final进行修饰; * 3. 作用域 : 仅仅在定义它的方法或代码块中有效; * 4. 局部内部类 访问 外部类的成员 : 直接访问即可; * 5. 外部类 访问 局部内部类的成员 : 创建对象 -> 通过对象进行访问, * 注意 : 需要在局部内部类的作用域中才可以; * 6. 如果 外部类 和 局部内部类 的成员重名时,默认遵循就近原则, * 如果就是想访问 外部类的成员时,使用 【外部类名.this.成员】 的方式
3.案例代码
3.1 局部内部类的定义代码
各位coder一定要跟着上面的特性来看这一段代码。
package com.northcastle.A_jubu_innerClass; public class JubuInnerClass { // 1.外部类的属性 private String field01 = "外部类的私有属性field01"; public String field02 = "外部类的共有属性field02"; // 2.外部类的构造器 public JubuInnerClass() { } public JubuInnerClass(String field01, String field02) { this.field01 = field01; this.field02 = field02; } // 3.外部类的方法 public void method01(){ System.out.println("== 外部类的共有方法 : method01 "); } private void method02(){ System.out.println("== 外部类的私有方法 : method02 "); } // * 包含内部类的方法 public void method03(){ System.out.println("== 外部类的方法03 begin : 此方法包含一个局部内部类 == "); System.out.println(); // 下面开始编写 局部内部类的代码 class innerClass{ // 1.局部内部类 的 属性 private String field01_inner = "局部内部类的私有属性"; public String field02_inner = "局部内部类的共有属性"; private String field02 = "局部内部类的和外部类重名的属性"; // 2.局部内部类的 构造器 public innerClass() { } public innerClass(String field01_inner, String field02_inner, String field02) { this.field01_inner = field01_inner; this.field02_inner = field02_inner; this.field02 = field02; } //3.局部内部类的方法 public void method01_inner(){ System.out.println("--> 这是局部内部类的方法 method01_inner : begin <--"); System.out.println("直接访问外部类的私有成员 field01 : "+field01); System.out.println("直接访问外部类的方法method01()、method02 :"); method01(); method02(); System.out.println("--> 这是局部内部类的方法 method01_inner : end <--"); } public void method02_inner(){ System.out.println("--> 这是局部内部类的方法 method02_inner 演示内部类如何访问同名的外部类的属性field02 begin <--"); System.out.println("外部类的属性 field02 : "+JubuInnerClass.this.field02); System.out.println("--> 这是局部内部类的方法 method02_inner 演示内部类如何访问同名的外部类的属性field02 end <--"); } } // innerClass end // 外部类访问内部类 : 创建内部类的对象,通过对象进行访问 innerClass innerClass = new innerClass(); innerClass.method01_inner(); System.out.println(); innerClass.method02_inner(); System.out.println(); System.out.println("== 外部类的方法03 end : 此方法包含一个局部内部类 == "); } }
3.2 局部内部类的使用代码
package com.northcastle.A_jubu_innerClass; public class Application { public static void main(String[] args) { //本代码演示使用内部类的情况 JubuInnerClass jubuInnerClass = new JubuInnerClass(); jubuInnerClass.method03(); } }
3.3 运行结果
4.完成
Congratulations!
You are one step closer to success! -
什么是内部类?成员内部类、静态内部类、局部内部类和匿名内部类的区别及作用?
2021-08-31 22:33:52一、什么是内部类?or 内部类的概念 内部类是定义在另一个类中的类;下面类TestB是类TestA的内部类。即内部类对象引用了实例化该内部对象的外围类对象。 public class TestA{ class TestB {} } 二、 为什么需要...一、什么是内部类?or 内部类的概念
内部类是定义在另一个类中的类;下面类TestB是类TestA的内部类。即内部类对象引用了实例化该内部对象的外围类对象。
public class TestA{ class TestB {} }
二、 为什么需要内部类?or 内部类有什么作用?
1、 内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据。
2、内部类可以对同一个包中的其他类隐藏起来。
3、 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。三、 内部类的分类
成员内部类,局部内部类,匿名内部类,静态内部类
3.1 成员内部类
成员内部类:存在于某个类的内部,与全局属性或者方法同级的内部类就是成员内部类。
举一个成员内部类实例:public class Person{ public void run(){} public class DoWork implements Work{} }
成员内部类特点:
1、(重要)成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括静态成员和私有成员)。!!很重要
2、成员内部类和外部类的属性和方法名同名时,外部类的属性和方法会隐藏;但可以通过外部类.this.成员变量的方式访问外部类的属性和方法。
3、 外部类必须通过成员内部类的对象来访问内部类的属性和方法。
4、 成员内部类对象会隐式的引用一个外部类对象。(可以解释第一点)
5、 成员内部类可以有public\private\protected以及默认访问权限。3.2 局部内部类
举一个局部内部类实例:
public class Person{ public void run(){ class DoWork implements Work{} } }
注意:和成员内部类的区别,局部内部类在方法里面
局部内部类:是定义在一个方法或者一个作用域里面的类。它与成员内部类的区别在于局部内部类的访问仅在于方法内或者作用域内。
局部内部类的特点:1、 不能有private、public、protected和static等修饰符,与局部变量类似。
2、只能在定义局部内部类的方法或者作用域中实例化;
3、 局部内部类的对象不能使用该内部类所在方法或者作用域的非final局部变量(为什么?);3.3 匿名内部类
举一个匿名内部类实例:public class Person{ public DoWork doSomething(){ return new DoWork(){ public void do(){} }; } }
什么是匿名内部类:不定义类的名字,在使用的地方直接定义对象。
匿名内部类的特点:1、唯一一种没有构造器的类;匿名内部类在编译时,编译器会自动起名xxx$1.class;
2、 匿名内部类不能存在任何静态的变量、方法等;
3、 匿名内部类是局部内部类的特例;
4、大部分匿名内部类用于接口返回;3.4 静态内部类
举一个静态内部类实例:
public class Person{ public void run(){} public static class DoWork implements Work{} }
注意和成员内部类的区别
静态内部类:在成员内部类的基础上加上一个static关键字就是静态内部类。
静态内部类的特点:1、不需要依赖外部类。
2、不能使用外部类的非静态属性和方法。例题:
下列说法正确的是(AB)?
A、对于局部内部类,只有在方法的局部变量被标记为final或局部变量是effctively final的,内部类才能使用它们
B、 成员内部类位于外部类内部,可以直接调用外部类的所有方法(静态方法和非静态方法)
C、由于匿名内部类只能用在方法内部,所以匿名内部类的用法与局部内部类是一致的
D、静态内部类可以直接访问外部类的非静态成员 -
Java局部内部类和匿名内部类定义与用法实例分析
2020-08-25 18:39:29主要介绍了Java局部内部类和匿名内部类,结合实例形式分析了java局部内部类和匿名内部类相关定义、原理与用法,需要的朋友可以参考下 -
内部类之局部内部类只能访问final的局部变量
2020-12-15 19:57:591.首先来了解一下局部内部类是如何访问局部变量的 Person类是外部类,LoInClassIntf是接口,localInClassRe是Person类的成员方法,且返回值类型为LoInClassIntf; 方法内定义了一个局部内部类LoInnerClass,该内部...1.首先来了解一下局部内部类是如何访问局部变量的
Person类是外部类,LoInClassIntf是接口,localInClassRe是Person类的成员方法,且返回值类型为LoInClassIntf;
方法内定义了一个局部内部类LoInnerClass,该内部类实现了接口LoInClassIntf;
方法内还定义了一个final的局部变量a,定义了一个LoInnerClass类型的对象引用loInC;
代码如下:
1 //笔记23:内部类--局部内部类--实现接口,返回内部类对象 2 //接口 3 public interface LoInClassIntf { 4 void test(); 5 } 6 7 //方法localInClassRe,返回值为LoInClassIntf,局部内部类来实现该接口,向上转型 8 public LoInClassIntf localInClassRe() { 9 final int a = 1; //常量 10 11 //笔记23--内部类--局部内部类--实现接口 12 class LoInnerClass implements LoInClassIntf { 13 public void test() { 14 System.out.println("variable a:" + a); 15 } 16 } 17 18 LoInnerClass loInC = new LoInnerClass(); 19 return loInC; 20 } 21 22 public static void main(String[] args) { 23 //笔记23--局部内部类 24 Person per = new Person(); 25 26 LoInClassIntf lInCIntf = per.localInClassRe(); 27 lInCIntf.test(); 28 }
输出结果为:
1 variable a:1
成员方法localInClassRe执行中的内存示意图如下:
成员方法localInClassRe执行后的内存示意图如下:
分析:
成员方法localInClassRe执行后,方法体中的局部变量a和对象引用loInC都被释放掉了,但分配在堆中的对象未回收,这时由main方法中的局部变量lInCIntf来指向它;
到这里还没什么问题,但第27行,lInCIntf调用了test方法,test方法中访问到了成员方法localInClassRe中的局部变量a,而a此时已不存在了,所以就会出现错误;
即,局部变量与局部内部类的对象的生命周期不同;
为解决这一问题,Java把局部内部类要访问的局部变量重新拷贝了一份,并把备份放在内部类的常量池中,这样不论方法有没有执行结束,拷贝都是存在的,就不会再出现访问不存在的变量的错误了。
成员方法localInClassRe执行中的内存示意图如下:
成员方法localInClassRe执行后的内存示意图如下:
上面涉及到的局部变量a是方法体内定义的,如果局部内部类访问的是方法体的参数呢?
Java采取的方法是,默认为局部内部类的构造方法传入该参数作为构造方法的参数,然后用该参数来初始化内部类中拷贝的变量a。
局部内部类如何访问局部变量的问题解决了,那么为什么只能访问final的局部变量呢?
2.数据同步的问题
上面通过拷贝一份局部变量来解决生命周期不同的问题,如果方法体和局部内部类都改变了a的值会怎么样呢?
如下图所示:
这样两个a不一致,就会出现数据不同步,下一步应该用a=2还是a=3呢?
为解决这个问题,Java规定局部内部类可访问的局部变量必须为final的,即内部类不能改变要访问的局部变量的值,这样就不会出现数据不同步的问题了
-
内部类与局部内部类
2018-08-19 08:31:22内部类与局部内部类 1、什么是内部类 将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。 1.成员内部类 :定义在类中方法外的类。 定义格式: class 外部类 { class内部类{ } ... -
Java ---- 局部内部类 静态内部类 普通内部类
2022-04-16 01:03:37Java ---- 局部内部类 静态内部类 普通内部类 -
Java 局部内部类、匿名内部类详解
2019-08-19 00:34:02外部类与内部类 众所周知,每个java文件必须有一个与这个java文件同名的外部类,这个外部类可以是public或default的。而除了这个同名外部类,还可以有与这个同名外部类平级的其他外部类,但它们必须是default的。 而... -
java基础_内部类、静态内部类、成员内部类、局部内部类、匿名内部类.doc
2020-07-31 00:12:10Java基础_内部类静态内部类成员内部类局部内部类匿名内部类 内部类 使用内部类减少了命名冲突 一个内部类可以定义在一个类中一个方法中甚至一个表达式中 内部类分为四种 静态内部类(static inner classes) 成员内部... -
局部内部类和匿名内部类使用局部变量为什么要final1
2022-08-08 21:37:03//从阅读角度,这里预期打印a=20,然而只会打印出a=10,会让人误解,因为在Inner的change()中修改的是Inner内部类对象的this.a,它是m -
C#匿名委托和Java匿名局部内部类使用方法示例
2020-09-04 21:22:48Java在嵌套类型这里提供的特性比较多,假设:Java的字节码只支持静态嵌套类,内部类、局部内部类和匿名局部内部类都是编译器提供的语法糖,这个假设目前没法验证(看不懂字节码),本文先来看一下C#是如何为我们提供... -
内部类详解————局部内部类
2018-05-05 23:10:07《内部类详解————局部内部类》 《内部类详解————静态嵌套类》 定义 在方法或某个作用域内的内部类,称为局部内部类。匿名内部类就是一种局部内部类。 实现方式 public class OutterType { public ... -
面试 | 什么是内部类?成员内部类、静态内部类、局部内部类和匿名内部类的区别及作用?
2019-06-05 07:32:551 内部类的概念 内部类是定义在另一个类中的类;下面类B是类A的内部类。即内部类对象引用了实例化该内部对象的外围类对象。 public class A{ class B {} } 2 为什么需要内部类?(来自JAVA核心技术) 内部类方法... -
lanlan2017#JavaReadingNotes#6.7.4 局部内部类1
2022-07-25 14:05:31- 第6章 面向对象(下)- 6.7 内部类6.7.4 局部内部类什么是局部内部类在方法里定义内部类就是一个局部内部类,局部内部类仅在该方法里有效。由于局部内部 -
Java内部类[成员内部类、局部内部类、匿名内部类和静态内部类],代码讲解
2020-03-16 10:21:37* 标题:Java内部类[成员内部类、局部内部类、匿名内部类和静态内部类] * * 作者:Nstar * * 时间:2020年3月13日 * * 内容: * * 问:什么是内部类? * 答:在 Java 中,可以将一个类定义在另一个类里面或者一... -
大数据 -- java基础9 成员内部类 、局部内部类及匿名内部类用法详解
2022-01-19 20:00:501、内部类: 把类定义在其他类的内部,称之为内部类。 内部类有哪些特点: (1)内部类可以访问外部类的成员,包括私有。 (2)外部类要想访问内部类的成员,必须要创建内部类的对象。 按照内部类在类中定义... -
java 局部内部类的使用规范
2010-06-21 15:00:42java 局部内部类的使用规范 java 局部内部类的使用规范 -
java局部内部类和匿名内部类
2019-06-16 11:46:281.局部内部类 java局部内部类就是在方法中定义的类,它仅在该方法中有效。因为它不能在该方法之外使用,因此它不能使用访问控制符和static修饰。它的应用场景是:在java代理模式中,可以直接在方法中用局部内部类... -
如何调用局部内部类中的方法
2021-05-15 18:06:442.内部类的分类:成员内部类(静态、非静态) vs 局部内部类(方法内、代码块内、构造器内) 3.成员内部类: 一方面,作为外部类的成员: >调用外部类的结构 >可以被static修饰 >可以被4种不同的权限... -
Java 局部内部类访问局部变量为什么必须加final关键字
2021-07-02 15:10:18在Java中,局部内部类如果调用了方法中的变量,那么该变量必须申明为final类型,如果不申明,则编译就会出错。 这里的内部类指的是方法内部类或匿名内部类,不包含静态内部类和成员内部类 这里通过一个例子类分析 ... -
局部内部类和匿名内部类
2019-06-22 07:54:37一局部内部类 1点睛 内部类不仅可以在类中定义,也可以定义在方法体或作用域内。这样的内部类作用范围仅限于方法体或特定的作用域内,因此也称为局部内部类。 2代码 class InnerClassTest { int score = 95; ... -
局部内部类是否可以访问非final变量(局部内部类为什么只能访问final修饰的局部变量)?;局部内部类为什么...
2019-09-05 23:00:15局部内部类是否可以访问非final变量: 不能访问局部的,可以访问成员变量(全局的)。 当方法执行完以后,就会出栈,属性也就没有了,但局部内部类的对象可能还在被其他对象引用,但调用的局部属性却没有了,所以,... -
day11 11 局部内部类定义
2021-08-31 11:21:42day11_11_局部内部类定义 -
关于内部类的问题: 局部内部类访问外部类的局部变量问题(原理性问题)
2019-06-17 14:17:31关于内部类的问题: 局部内部类访问外部类的局部变量问题 编程时,在线程中使用局部变量时候经常编译器会提示:局部变量必须声明为final [java] view plain copy package test; public class ThreadTest { ... -
局部内部类访问外部类的局部变量
2017-03-13 15:28:16在书上看到这样一段话:如果局部内部类要访问外部类的局部变量,则此变量必须是final修饰的,否则不能访问。说是为了提高局部变量的生命周期,可不可以说的通俗一些? -
方法内部类(局部内部类)
2018-08-17 14:15:29(一)方法内部类(又名局部内部类) :由名字可知,该内部类是写在一个方法里面的,其用法如下: 1.方法内部类的地位和方法里面的局部变量相似,所以不能用public等修饰词修饰; 2.方法内部类只能在声明的... -
内部类,局部内部类与匿名内部类创建对象方法
2018-08-03 20:37:00内部类: 定义在A类中的B类就是内部类,B类在A类中的地位和其他成员相同,意思就是说可以相互调用 优点:通过内部类可以让java间接的实现多继承 创建内部类的对象 方法一 先获取内部类对象再调用方法 ... -
为什么局部内部类和匿名内部类只能访问final的局部变量?
2017-10-24 10:41:02最近在看内部类的时候,有一个疑惑:局部内部类和匿名内部类只能访问final的局部变量,看了几篇博客,明白了很多,下面来分析一下: