-
2019-09-29 20:00:34
局部内部类
如果一个类是定义在一个方法内部,那么他就是一个局部内部类。
//“局部”:只是当前所属的方法才能使用它,除了这个方法就不行了。
/*定义格式:- 修饰符 class 外部类名称{//
- 修饰符 返回值类型 外部类名称方法(参数列表)
- {class 局部内名称{//}}}*/
/*小结: - public >protected>(default)>private
- 外部类:public/(default)
- 成员内部类:public protected default private
- 局部内部类:什么都不能写。 —*/
局部内部类Outer
代码:public class Outer { public void method() { class Inner{ int num=10; //int num=20; public void methodinner() { System.out.println(num); } } Inner inner=new Inner();//只能在该方法中调用局部内部类的方法! inner.methodinner(); } }
主类:
代码:public class Demo01Main { public static void main(String[] args) { Outer obj=new Outer(); obj.method(); } }
注意事项:
/*局部内部类,如果希望访问所在方法的变量局部,那么这个局部变量必须是final的
- 备注:从java8开始,只要局部变量事实不变,那么final关键字可以省掉。
原因(为什么用final修饰) - 1.new来出的对象在堆内存中
- 2.局部变量跟着方法邹,在栈中
- 3.方法运行结束后,立即出栈,局部变量就会消失。
- 4.但是new出来的对象还在堆中,直到垃圾回收,如果上述过程执行完毕,对象还想调用局部变量的值,无法调用。所以使用final关键字来修饰。*/
举例:
代码:
public class MyOuter {int num=10; public void method() { class Myinner { /*final*/ int num=20; // num=30;无法更改,fianl定义了! public void methodinner() { System.out.println(MyOuter.this.num);//10 System.out.println(this.num);//20 } } Myinner myinner=new Myinner(); myinner.methodinner(); }
}
更多相关内容 -
C#匿名委托和Java匿名局部内部类使用方法示例
2020-09-04 21:22:48Java在嵌套类型这里提供的特性比较多,假设:Java的字节码只支持静态嵌套类,内部类、局部内部类和匿名局部内部类都是编译器提供的语法糖,这个假设目前没法验证(看不懂字节码),本文先来看一下C#是如何为我们提供... -
Java局部内部类和匿名内部类定义与用法实例分析
2020-08-25 18:39:29主要介绍了Java局部内部类和匿名内部类,结合实例形式分析了java局部内部类和匿名内部类相关定义、原理与用法,需要的朋友可以参考下 -
详细分析Java内部类——局部内部类
2020-08-24 20:20:56主要介绍了Java局部内部类的相关资料,帮助大家更好的理解和学习Java 内部类的知识,感兴趣的朋友可以了解下 -
Java局部内部类原理与用法实例分析
2020-08-25 14:09:35主要介绍了Java局部内部类原理与用法,结合实例形式分析了Java局部内部类功能、用法及相关操作注意事项,需要的朋友可以参考下 -
java 局部内部类的使用规范
2010-06-21 15:00:42java 局部内部类的使用规范 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的,即内部类不能改变要访问的局部变量的值,这样就不会出现数据不同步的问题了
-
java内部类之成员内部类、局部内部类和匿名内部类
2018-07-15 16:13:302、局部内部类(包含匿名内部类)。 成员内部类 定义格式: 修饰符 class 类名称 { 修饰符 class 类名称 { //... } //... } 注意: 内部类使用外部,可以随意访问,但是外部类使用内部类要借助内部类的对象...内部类概念
一个类中包含另外一个类。
分类
- 成员内部类。
- 局部内部类(包含匿名内部类)。
成员内部类
定义格式:
修饰符 class 类名称 { 修饰符 class 类名称 { //... } //... }
注意:
内部类使用外部,可以随意访问,但是外部类使用内部类要借助内部类的对象。
使用成员内部类
两种方法:
1. 间接方式:在外部类的方法中,使用内部类,然后main只调用外部类的方法。
2. 直接方式:公式:
一般类:类名称 对象名 = new 类名称();
成员内部类:外部内名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();
Body.java含有一个内部类Heart
public class Body { private String name; //外部类方法 public void methodBody() { System.out.println("外部类的方法"); new Heart().beat();//在外部类方法中使用内部类。 } public class Heart { //成员内部类 //内部类方法 public void beat() { System.out.println("心脏跳动"); System.out.println("我叫:"+name); } } }
下面分别介绍两种方式访问内部类:
间接方式访问内部类
Demo01InnerClass.java
public class Demo01InnerClass { public static void main(String[] args) { Body body = new Body();//外部类对象 //通过外部类的对象,调用外部类的方法,里面间接使用内部类Heart body.methodBody();
直接方式访问内部类
public class Demo01InnerClass { public static void main(String[] args) { Body body = new Body();//外部类对对象 //外部内名称.内部类名称 对象名 = new 外部类名称().new 内部类名称(); Body.Heart heart = new Body().new Heart(); heart.beat(); } }
外部类和内部类变量重名问题
当外部类的变量和内部类变量重名时,在内部类方法中访问外部类变量的格式是:
外部类.this.外部类成员变量名
public class Outer { int number = 10; public class Inner { int number = 20; public void methodInner() { int number =30;//内部类方法的局部变量 System.out.println(number);//就近原则 System.out.println(this.number); System.out.println(Outer.this.number);//外部类的成员变量 } } }
30
20
10
局部内部类
如果类是定义在一个方法内部的,那么这就是一个局部内部类。
“局部”:只有当前所属的方法才能使用它,出了这个方法外面就不能用了。定义格式
:修饰符 class 外部类名称 { 修饰符 返回值类型 外部类方法名称(参数列表) { class 局部内部类名称 { //... } } }
Outer.java
含有局部内部类public class Outer { public void methodOuter() { class Inner { int num = 10; public void methodInner() { System.out.println(num);//10 } } //这个内部列只有当前所属方法能够访问这个类,出了这个方法就不能用了 Inner inner = new Inner(); inner.methodInner(); } }
DemoMain.java
public class DemoMain { public static void main(String[] args) { Outer outer = new Outer(); outer.methodOuter(); } }
结果:
10
注意:
局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是【有效final的】
备注:从java 8+开始,只要局部变量事实不变,那么final关键字可以省略。
原因:
1. new 出来的对象在堆内存当中。
2. 局部变量是跟着方法走的,在栈内存当中。
3. 方法运行结束后,立刻出栈,局部变量就会立刻消失。
4. 但是new出来的对象在堆当中持续存在,直到垃圾回收消失。public class MyOuter { public void methodOuter() { final int num = 10;//所在方法的局部变量 /*在栈中的局部变量可能随着方法结束出栈消失了,但是创建的内部类对象还存在。 对象使用常量时能直接将常量copy进来,这时就要保证这个常量是不可更改的,也就是final。 */ //num = 20; class MyInner { public void methodInner() { System.out.println(num); } } Inner myinner = new MyInner(); inner.methodInner(); } }
修饰内部类的权限
public > protected > (default) > private
定义一个类的时候,权限修饰符规则:- 外部类:public / (default)
- 成员内部类:都可以写,public > protected > (default) > private
- 局部内部类:什么都不能写,但不是de
匿名内部类
如果接口的实现类(或者是父类的子类)只需要使用唯一的一次。
那么这种情况下就可以省略调该类的定义,而改为使用【匿名内部类】。匿名内部类定义格式:
接口名称 对象名 = new 类名或者接口名称() { //覆盖重写所有抽象方法 };
代表继承了或者实现了该接口的子类对象。
==
接口MyInterface.java
==public interface MyInterface { void method1();//抽象方法 void method2(); }
==接口实现类
MyInterfaceImp.java
==public class MyInterfaceImpl implements MyInterface { @Override public void method1() { System.out.println("实现类覆盖重写了方法1"); } @Override public void method2() { System.out.println("实现了覆盖重写方法2"); } }
测试类
一、一般接口实现方法
DemoMain.java
public class DemoMain { public static void main(String[] args) { // MyInterface impl = new MyInterfaceImpl(); // impl.method(); } }
匿名内部类实现接口
DemoMain.java
public class DemoMain { public static void main(String[] args) { //使用匿名内部类,但不匿名对象,对象名称就叫obj MyInterface objA = new MyInterface() { @Override public void method1() { System.out.println("匿名内部类实现了方法1-A"); } @Override public void method2() { System.out.println("匿名内部类实现了方法2-A"); } }; objA.method1(); objA.method2(); System.out.println("----------我是分割线----------"); //使用匿名内部类,而且省略了对象名称,也是匿名对象 new MyInterface() { @Override public void method1() { System.out.println("匿名内部类实现了方法1-B"); } @Override public void method2() { System.out.println("匿名内部类实现了方法2-B"); } }.method1(); } }
结果:
匿名内部类实现了方法1-A
匿名内部类实现了方法2-A
----------我是分割线----------
匿名内部类实现了方法1-B
匿名内部内应用
- 实现倒计时5秒。
public class Demo02_Time { public static void main(String[] args) { Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { System.out.println("倒计时5秒"); } },5000);//倒计时5秒 } }
注意事项:
对格式进行解析:
"new 接口名称 {...};"
进行解析- new代表创建对象的动作
- 接口名称就是匿名内部类需要实现那个接口
- {…}这才是匿名内部类的内容
注意:
这个类只需要使用一次。匿名内部类在创建对象时,只能使用唯一一次。
如果希望多次希望多次创建对象,而且内容一样的话,那么就必须使用单独定义的实现类。匿名对象,在调用的时候,只能调用唯一一次。
如果希望同一个对象,调用多次方法,那么必须给对象取一个名字。匿名内部类是省略了【实现类/子类】,但是匿名对象是省略了【对象命名】。
强调:匿名和匿名对象不是一回事。
-
内部类与局部内部类
2018-08-19 08:31:22内部类与局部内部类 1、什么是内部类 将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。 1.成员内部类 :定义在类中方法外的类。 定义格式: class 外部类 { class内部类{ } ...内部类与局部内部类
1、什么是内部类
将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。
1.成员内部类 :定义在类中方法外的类。
定义格式:
class 外部类 {
class内部类{
}
}
2.访问特点
内部类可以直接访问外部类的成员,包括私有成员。 外部类要访问内部类的成员,必须要建立内部类的对象。
创建内部类对象格式:
外部类名.内部类名 对象名=new 外部类名().new 内部类名()
举例代码:
1.内部类
package DemoTest.DemoTest2;
public class person {
private String name;
public class xianren{
public void XianShow(){
System.out.println("仙人模式!");
System.out.println("我叫"+name);
}
}public void show(){
System.out.println("间接调用内部类!");
xianren xr = new xianren();
xr.XianShow();
}
public person() {
}
public person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}}
2.测试类
package DemoTest.DemoTest2;
public class Test {
public static void main(String[] args) {//第一种调用方法
person p = new person();
p.setName("鸣人");
p.show();
System.out.println("========================");//第二种调用方法
person.xianren x = p.new xianren();
x.XianShow();
System.out.println("========================");//第三种调用方法
//外部类名.内部类名 对象名=new 外部类名().new 内部类名()
person.xianren obj= new person("鸣人").new xianren();
obj.XianShow();
}
}3.结果:
间接调用内部类!
仙人模式!
我叫鸣人
========================
仙人模式!
我叫鸣人
========================
仙人模式!
我叫鸣人
举例代码2:
获取不同地址的值
1.不同位置的num
public class Denoquzhi {
int num=10;
class Quzhi{
int num=20;
public void print(){
int num=30;
System.out.println(num);
System.out.println(this.num);
System.out.println(Denoquzhi.this.num);
}
}
public void da(){
System.out.println("间接调用");
Quzhi q = new Quzhi();
q.print();
}
}2.测试类
package DemoTest.Demoquzhi;
public class Teat {
public static void main(String[] args) {//间接调用
Denoquzhi d = new Denoquzhi();
d.da();
System.out.println("===================");//格式规定的直接调用
Denoquzhi.Quzhi dui=new Denoquzhi().new Quzhi();
dui.print();
}
}3.结果:
间接调用
30
20
10
===================
30
20
10
2、局部内部类
举例代码:
1.在类的方法内包含了一个内部类
package DemoTest.DemoSamill;
public class Demosamill {
public void method(){
class MethodClass{
int num=10;
public void print(){
System.out.println("局部内部类");
System.out.println(num);
}
}
MethodClass m = new MethodClass();
m.print();
}
}2.测试类
package DemoTest.DemoSamill;
public class Test {
public static void main(String[] args) {
Demosamill d = new Demosamill();
d.method();
}
}3.结果
局部内部类
10
-
内部类详解————局部内部类
2018-05-05 23:10:07《内部类详解————局部内部类》 《内部类详解————静态嵌套类》 定义 在方法或某个作用域内的内部类,称为局部内部类。匿名内部类就是一种局部内部类。 实现方式 public class OutterType { public ... -
java基础:局部内部类和匿名内部类访问局部变量的时候,为什么变量必须要加上final?
2020-03-01 23:34:15因为生命周期不一致, 局部变量直接存储在栈中,当方法执行结束后,非final的局部变量就被销毁。而局部内部类对局部变量的...加了final,可以确保局部内部类使用的变量与外层的局部变量区分开,解决了这个问题。 ... -
Java ---- 局部内部类 静态内部类 普通内部类
2022-04-16 01:03:37Java ---- 局部内部类 静态内部类 普通内部类 -
Java 局部内部类、匿名内部类详解
2019-08-19 00:34:02外部类与内部类 众所周知,每个java文件必须有一个与这个java文件同名的外部类,这个外部类可以是public或default的。而除了这个同名外部类,还可以有与这个同名外部类平级的其他外部类,但它们必须是default的。 而... -
java:面向对象-局部内部类访问局部变量的问题
2018-09-27 16:34:12* 局部内部类访问局部变量必须用final修饰* 局部内部类在访问他所在方法中的局部变量必须用final修饰,为什么? 因为当调用这个方法时,局部变量如果没有用final修饰,他的生命周期和方法的生命周期是一样的,当方法弹栈,... -
java基础_内部类、静态内部类、成员内部类、局部内部类、匿名内部类.doc
2020-07-31 00:12:10Java基础_内部类静态内部类成员内部类局部内部类匿名内部类 内部类 使用内部类减少了命名冲突 一个内部类可以定义在一个类中一个方法中甚至一个表达式中 内部类分为四种 静态内部类(static inner classes) 成员内部... -
面试 | 什么是内部类?成员内部类、静态内部类、局部内部类和匿名内部类的区别及作用?
2019-06-05 07:32:551 内部类的概念 内部类是定义在另一个类中的类;下面类B是类A的内部类。即内部类对象引用了实例化该内部对象的外围类对象。 public class A{ class B {} } 2 为什么需要内部类?(来自JAVA核心技术) 内部类方法... -
java调用局部内部类中的方法
2019-08-09 12:21:26局部内部类中方法的调用 -
JAVA局部内部类的使用
2017-04-22 00:00:11我是在JDK8环境下实现的,与之前的版本规则有一些变化,所以在这里mark一下 public class localInnerClass{ public static void main(String []args)... //因为是顺序编译,要在内部类后面创建实例。 } } -
JDK8之前,匿名内部类访问的局部变量为什么必须要用final修饰
2018-08-15 20:17:51这里到了问题的核心了,如果局部变量发生变化后,匿名内部类是不知道的(因为他只是拷贝了局不变量的值,并不是直接使用的局部变量)。这里举个栗子:原先局部变量指向的是对象A,在创建匿名内部类后,匿名内部类中... -
java局部内部类和匿名内部类
2019-06-16 11:46:281.局部内部类 java局部内部类就是在方法中定义的类,它仅在该方法中有效。因为它不能在该方法之外使用,因此它不能使用访问控制符和static修饰。它的应用场景是:在java代理模式中,可以直接在方法中用局部内部类... -
局部内部类访问外部类的局部变量
2017-03-13 15:28:16在书上看到这样一段话:如果局部内部类要访问外部类的局部变量,则此变量必须是final修饰的,否则不能访问。说是为了提高局部变量的生命周期,可不可以说的通俗一些? -
Java内部类[成员内部类、局部内部类、匿名内部类和静态内部类],代码讲解
2020-03-16 10:21:37* 标题:Java内部类[成员内部类、局部内部类、匿名内部类和静态内部类] * * 作者:Nstar * * 时间:2020年3月13日 * * 内容: * * 问:什么是内部类? * 答:在 Java 中,可以将一个类定义在另一个类里面或者一... -
局部内部类和匿名内部类
2019-06-22 07:54:37一局部内部类 1点睛 内部类不仅可以在类中定义,也可以定义在方法体或作用域内。这样的内部类作用范围仅限于方法体或特定的作用域内,因此也称为局部内部类。 2代码 class InnerClassTest { int score = 95; ... -
局部内部类访问局部变量时,变量必须用final修饰
2018-10-24 10:15:02此时的局部内部类(定义在方法中的内部类)InTest中的f()访问了外部类中的局部变量x。这里x并没有用final修饰(1.8之后java隐式的将x修饰为final)如果你添加一个x=8,这里就会报错。 为什么要用final修饰 主要... -
如何调用局部内部类中的方法
2021-05-15 18:06:442.内部类的分类:成员内部类(静态、非静态) vs 局部内部类(方法内、代码块内、构造器内) 3.成员内部类: 一方面,作为外部类的成员: >调用外部类的结构 >可以被static修饰 >可以被4种不同的权限... -
Java内部类:成员内部类、局部内部类、匿名内部类详解
2020-03-10 10:54:45局部内部类(包含匿名内部类) 成员内部类 定义格式: 修饰符 class 外部类名称 { 修饰符 class 内部类名称 { // .... } // .... } 内部类的class文件命名为:外部类$内部类.class 使用成员内部类 间接方式:... -
以下关于 Java 的局部内部类的说法错误的是
2021-03-09 06:46:26以下关于 Java 的局部内部类的说法错误的是答:局部内部类可以访问外部类的所有成员关于赋值语句,以下选项中描述错误的是:答:设 a = 10;b = 20,执行 a,b = a,a + b print(a,b) 和 a = b b = a + b print(a,b) ... -
为什么局部内部类和匿名内部类只能访问final的局部变量?
2017-10-24 10:41:02最近在看内部类的时候,有一个疑惑:局部内部类和匿名内部类只能访问final的局部变量,看了几篇博客,明白了很多,下面来分析一下: -
java 内部类 局部内部类 匿名类 实例代码
2011-04-02 10:58:08java 内部类 实例内部类 局部内部类 匿名类 静态内部类 实例代码