-
2018-03-27 18:57:52
在方法中定义内部类
理论上内部类可以定义在类中的任意位置上,这就包括了:类、方法、代码块中。
不过如果从实用角度上讲在方法中定义内部类的形式是最多的。
范例:在方法中定义内部类
class Outer{//定义一个外部类 private static String msg="hello world!"; public void fun(int num) { class Inner{ public void print() { System.out.println("msg = "+msg); System.out.println("num = "+num); } } new Inner().print(); //产生内部类对象并调用方法 } } public class TestDemo { public static void main(String args[]) { new Outer().fun(100);// 产生外部类对象并调用方法 } }
此时的代码块在JDK1.8是正常的,但是在1.8之前一定是错误的。(现在使用最多的是1.7)
在jdk1.7及以前,
如果一个内部类定义在了方法之中,那么该内部类要想访问方法中的参数
那么这个参数前必须使用final定义。而1.8之后为了推广它的函数式编程,所以将一局限取消了
内部类的使用暂时不作为现阶段设计的首选。
但是至少应该知道,内部类具备的特点
|-破坏了程序的结构
|-方便的进行私有属性的访问;
以后如果发现类名称上出现了“.”应该立刻想到是内部类的概念
更多相关内容 -
Java内部类和匿名内部类的用法
2016-07-21 15:46:41Java内部类和匿名内部类的用法 【尊重原创,转载请注明出处】http://blog.csdn.net/guyuealian/article/details/51981163一、内部类: (1)内部类的同名方法 内部类可以调用外部类的方法,如果内部类有同名方法...Java内部类和匿名内部类的用法
一、内部类:(1)内部类的同名方法内部类可以调用外部类的方法,如果内部类有同名方法必须使用"OuterClass.this.MethodName()"格式调用(其中OuterClass与MethodName换成实际外部类名及其方法;this为关键字,表示对外部类的引用);若内部类无同名方法可以直接调用外部类的方法。
但外围类无法直接调用内部类的private方法,外部类同样无法直接调用其它类的private方法。注意:内部类直接使用外部类的方法与该方法的权限与是否static无关,它取决于内部类是否有同名方法。package innerclass; public class OuterClass { private void outerMethod() { System.out.println("It's Method of OuterClass"); } public static void main(String[] args) { OuterClass t = new OuterClass(); OuterClass.Innerclass in = t.new Innerclass(); in.innerMethod(); } class Innerclass { public void innerMethod() { OuterClass.this.outerMethod();// 内部类成员方法与外部类成员方法同名时,使用this调用外部类的方法 outerMethod();// 内部类没有同名方法时执行外部类的方法 } private void outerMethod() { System.out.println("It's Method of Innerclass"); } } }
输出结果为:It's Method of OuterClass It's Method of Innerclass
(2)内部类访问外部类的变量必须声明为final
方法中的局部变量,方法结束后这个变量就要释放掉,final保证这个变量始终指向一个对象。
首先,内部类和外部类其实是处于同一个级别,内部类不会因为定义在方法中就会随着方法的执行完毕而跟随者被销毁。问题就来了,如果外部类的方法中的变量不定义final,那么当外部类方法执行完毕的时候,这个局部变量肯定也就被GC了,然而内部类的某个方法还没有执行完,这个时候他所引用的外部变量已经找不到了。如果定义为final,java会将这个变量复制一份作为成员变量内置于内部类中,这样的话,由于final所修饰的值始终无法改变,所以这个变量所指向的内存区域就不会变。注意,若使用JDK1.8,方法中内部类的方法是可以直接访问外部类的方法的局部变量,并且不需要声明为final类型。public class OuterClass { int num1 = 0;// 成员变量 private void outerMethod() { int num2 = 0;// 方法内的局部变量 class Innerclass_1 { public void innerMethod() { System.out.println(num1);// 方法中内部类的方法,可以正常访问外部类的成员变量 System.out.println(num2);// JDK1.8以前,方法中内部类的方法,不能直接访问外部类的方法的局部变量,必须声明为final } } } }
如果使用JDK1.8以前的版本,Eclipse会出现如下错误提示:
(3)内部类的实例化内部类实例化不同于普通类,普通类可以在任意需要的时候实例化,而内部类必须在外层类实例化以后方可实例化,并与外部类建立关系
因此在外部类中的非static方法中,是可以实例化内部类对象private void outerMethod() { System.out.println("It's Method of OuterClass"); Innerclass in = new Innerclass();//在外部类的outerMethod方法中实例化内部类是可以啊 }
No enclosing instance of type OuterClass is accessible. Must qualify the allocation with an enclosing instance of type OuterClass (e.g. x.new A() where x is an instance of OuterClass).这是因为静态方法是在类实例化之前就可以使用的,通过类名调用,这时动态内部类都还没实例化呢,怎么用,总不能调用一个不存在的东西吧。如果想在Static方法中new内部类,可以把内部类声明为Static
当然,一般不使用static的方式,而是推荐这种方法:x.new A() ,其中 x是外部类OuterClass的实例,A是内部类Innerclasspublic class OuterClass { private void outerMethod() { System.out.println("It's Method of OuterClass"); } public static void main(String[] args) { Innerclass in = new Innerclass(); in.innerMethod(); } static class Innerclass {//把内部类声明为static public void innerMethod() { System.out.println("It's Method of innerMethod"); } } }
x.new A() ,其中 x是外部类OuterClass的实例,A是类部类Innerclass,当然可以拆分如下,这样就显然很明白啦:package innerclass; public class OuterClass { private void outerMethod() { System.out.println("It's Method of OuterClass"); } public static void main(String[] args) { OuterClass.Innerclass in = new OuterClass().new Innerclass();//使用x.new A()的方式 in.innerMethod(); } class Innerclass { public void innerMethod() { System.out.println("It's Method of innerMethod"); } } }
public static void main(String[] args) { OuterClass out = new OuterClass();//外部实例 OuterClass.Innerclass in = out.new Innerclass();//外部实例.new 外部类 in.innerMethod(); }
(4)什么情况下使用内部类
典型的情况是,内部类继承自某个类或实现某个接口,内部类的代码操作创建其的外层类的对象。所以你可以认为内部类提供了某种进
入其外层类的窗口。
使用内部类最吸引人的原因是:每个内部类都能独立地继承自一个(接口的)实现,所以无论外层类是否已经继承了某个(接口的)实
现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角
度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。(5)在静态方法中实例化内部类例子:(内部类放在静态方法中)
per.speak()可调用,而per.say()不能调用,这时因为per是Person对象,要想调用子类的方法,可以强制向下转型为:((Boy) per).say();或者直接改为Boy per = new Boy();。 从中可发现,要想调用内部类的自定义的方法,必须通过内部类的对象来调用。那么,匿名内部类连名字都没有,怎么调用内部类自定义的方法?package javatest2; public class JavaTest2 { public static void main(String[] args) { class Boy implements Person { public void say() {// 匿名内部类自定义的方法say System.out.println("say方法调用"); } @Override public void speak() {// 实现接口的的方法speak System.out.println("speak方法调用"); } } Person per = new Boy(); per.speak();// 可调用 per.say();// 不能调用 } } interface Person { public void speak(); }
(二)匿名内部类匿名内部类也就是没有名字的内部类正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写,但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口,但最多只能继承一个父类,或实现一个接口。
关于匿名内部类还有如下两条规则:
1)匿名内部类不能是抽象类,因为系统在创建匿名内部类的时候,会立即创建内部类的对象。因此不允许将匿名内部类定义成抽象类。
2)匿名内部类不等定义构造器(构造方法),因为匿名内部类没有类名,所以无法定义构造器,但匿名内部类可以定义实例初始化块,怎样判断一个匿名类的存在啊?看不见名字,感觉只是父类new出一个对象而已,没有匿名类的名字。
先看段伪代码
一般来说,new 一个对象时小括号后应该是分号,也就是new出对象该语句就结束了。但是出现匿名内部类就不一样,小括号后跟的是大括号,大括号中是该new 出对象的具体的实现方法。因为我们知道,一个抽象类是不能直接new 的,必须先有实现类了我们才能new出它的实现类。上面的伪代码就是表示new 的是Father的实现类,这个实现类是个匿名内部类。abstract class Father(){ .... } public class Test{ Father f1 = new Father(){ .... } //这里就是有个匿名内部类 }
其实拆分上面的匿名内部类可为:
class SonOne extends Father{ ... //这里的代码和上面匿名内部类,大括号中的代码是一样的 } public class Test{ Father f1 = new SonOne() ; }
先看一个例子,体会一下匿名内部类的用法:
运行结果:eat something
可以看到,我们直接将抽象类Person中的方法在大括号中实现了,这样便可以省略一个类的书写。并且,匿名内部类还能用于接口上
这里per.speak()是可以正常调用的,但per.say()不能调用,为什么呢?注意Person per = new Person()创建的是Person的对象,而非匿名内部类的对象。其实匿名内部类连名字都没有,你咋实例对象去调用它的方法呢?但继承父类的方法和实现的方法是可以正常调用的,本例子中,匿名内部类实现了接口Person的speak方法,因此可以借助Person的对象去调用。public class JavaTest2 { public static void main(String[] args) { Person per = new Person() { public void say() {// 匿名内部类自定义的方法say System.out.println("say方法调用"); } @Override public void speak() {// 实现接口的的方法speak System.out.println("speak方法调用"); } }; per.speak();// 可调用 per.say();// 出错,不能调用 } } interface Person { public void speak(); }
若你确实想调用匿名内部类的自定义的方法say(),当然也有方法:(1)类似于speak方法的使用,先在Person接口中声明say()方法,再在匿名内部类中覆写此方法。(2)其实匿名内部类中隐含一个匿名对象,通过该方法可以直接调用say()和speak()方法;代码修改如下:
public class JavaTest2 { public static void main(String[] args) { new Person() { public void say() {// 匿名内部类自定义的方法say System.out.println("say方法调用"); } @Override public void speak() {// 实现接口的的方法speak System.out.println("speak方法调用"); } }.say();// 直接调用匿名内部类的方法 } } interface Person { public void speak(); }
-
内部类的方法(外部调用内部类的方法)
2017-11-24 09:14:30外部调用内部类的方法1.使用static可以声明一个内部类, 可以直接在外部调用
class Outer{ // 定义外部类 private static String info = "hello world" ; // 定义外部类的私有属性 static class Inner{ // 使用static定义内部类为外部类 public void print(){ // 定义内部类的方法 System.out.println(info) ; // 直接访问外部类的私有属性 } }; public void fun(){ // 定义外部类的方法 new Inner().print() ; // 通过内部类的实例化对象调用方法 } }; public class InnerClassDemo03{ public static void main(String args[]){ new Outer.Inner().print() ; // 调用外部类的fun()方法 } };
2.不使用statc声明一个内部类 ,使外部调用
3.在方法中定义内部类 ,使外部调用class Outer{ // 定义外部类 private String info = "hello world" ; // 定义外部类的私有属性 class Inner{ // 定义内部类 public void print(){ // 定义内部类的方法 System.out.println(info) ; // 直接访问外部类的私有属性 } }; public void fun(){ // 定义外部类的方法 new Inner().print() ; // 通过内部类的实例化对象调用方法 } }; public class InnerClassDemo04{ public static void main(String args[]){ Outer out = new Outer() ; // 外部类实例化对象 Outer.Inner in = out.new Inner() ; // 实例化内部类对象 in.print() ; // 调用内部类的方法 } };
class Outer{ // 定义外部类 private String info = "hello world" ; // 定义外部类的私有属性 public void fun(final int temp){ // 定义外部类的方法 class Inner{ // 在方法中定义的内部类 public void print(){ // 定义内部类的方法 System.out.println("类中的属性:" + info) ; // 直接访问外部类的私有属性 System.out.println("方法中的参数:" + temp) ; } }; new Inner().print() ; // 通过内部类的实例化对象调用方法 } }; public class InnerClassDemo05{ public static void main(String args[]){ new Outer().fun(30) ; // 调用外部类的方法 } };
-
内部类如何调用外部类的方法
2019-09-28 17:18:45内部类如何调用外部类的方法 直接上代码 public class test{ public static void main(String[] args) { Outer.Inner p=new Outer().new Inner(); p.show(); } } class Outer{ int sum; class Inner{ ...内部类如何调用外部类的方法
直接上代码
public class test{ public static void main(String[] args) { Outer.Inner p=new Outer().new Inner(); p.show(); } } class Outer{ int sum; class Inner{ public void show(){ System.out.println("这是内部类的方法"); Outer.this.test(); //在内部类的方法中,直接外部类的名字+this+外部类方法名 } } public void test(){ System.out.println("这是一个外部类方法"); } }
新手,多多理解,多多交流。
-
Java——访问内部类的方法
2019-05-05 21:29:10内部类: 将一个类定义在另一个类的里面,对里面... • 而外部类要访问内部类中的成员必须要建立内部类的对象。 内部类的位置: 内部类定义在成员位置上 • 可以被private static成员修饰符修饰。 • 被stati... -
内部类(成员内部类、静态内部类、方法内部类)
2018-06-05 15:33:35一:成员内部类:最常见的内部类就是成员内部类,也...2、Inner类中定义的test()方法可以访问Outer类中的数据,不受访问控制符的影响。3、 定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去... -
Java 中的方法内部类
2018-07-24 11:31:45方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用。 一定要注意哦:由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和 ... -
Java如何在main方法中实例化内部类对象
2019-03-11 15:33:42今天我在实例化一个类是编译器报以下错误: No enclosing instance of type Person is accessible. Must qualify the allocation with an enclosing instance of type Person (e.g. x.new A() where x is an ... -
Java在外部类的方法中创建内部类对象
2017-09-16 19:19:09有时候需要在Java的外部类的一个方法中创建一个内部类的对象,下面用一个简单的小例子来说明一种实现方法。 public class Out { public Out(){ System.out.println("外部类创建"); } class In{ public ... -
java中的内部类内部接口详解
2020-05-08 06:24:42文章目录简介内部类静态内部类非静态内部类静态方法内部类非静态方法的内部类匿名类内部接口总结 简介 一般来说,我们创建类和接口的时候都是一个类一个文件,一个接口一个文件,但有时候为了方便或者某些特殊的原因... -
Java内部类的深入理解及各种内部类的访问
2020-03-26 23:27:38详细介绍了Java中的内部类的概念,及各种内部类的访问案例演示。包括非静态内部类、静态内部类、局部内部类、匿名内部类。 -
匿名内部类方法重写(很常用)
2020-05-19 11:38:47当我们在使用java的类作为参数时,经常会需要重写这个类中的某些方法。这个时候通常有两种方法:一是我们写一个类继承这个类并重写需要重写的方法,传参时用子类。二是使用匿名内部类的方式重写其方法,也可以达到... -
Java8:从匿名内部类到Lambda表达式&方法引用
2019-02-17 13:57:08匿名内部类、lambda和方法引用其实是相通的,从匿名内部类到lambda到方法引用是一个进化的过程,是一个简化的过程,更加是一个从抽象的过程。 作用都是实现接口方法,换句话说就是实现接口;只是这个接口只有一个... -
如何调用局部内部类中的方法
2018-04-01 10:12:57内部类:将类写在其他类的内部,可以写在其他类的成员位置和局部位置局部内部类:将类写在其他类的局部方法中例如public class outer { public void out(){ int i=2; class Inner{ int a=1; public void ... -
匿名内部类实现多线程,内部类调用外部方法中定义的变量
2017-09-13 09:50:08package Test;import java.util.Date;public class MyTread { /** * @author peter * @desc 启动多线程 推送消息到接口地址,匿名内部类调用外部方法属性 * @date 2017.09.13 */ public void test() { // -
java调用内部类的两种方法
2018-11-06 19:31:36//一、调用内部类的第一种方式,将内部类声明为static,直接通过总类调用 testList.add(new TestPrintList.User(3,"tom")); testList.add(new TestPrintList.User(4,"jack")); testList.add(new ... -
Java内部类的定义、如何创建内部类、内部类的分类、内部类与外部类的关系
2018-10-21 21:38:32文章目录1 内部类的基本概念1.1 内部类的定义1.2 内部类的优缺点2 创建内部类2.1 在外部类外部创建非静态内部类2.2 在外部类外部创建静态内部类...3.2 静态内部类3.3 方法内部类3.4 匿名内部类4 内部类与外部类的关系... -
成员内部类为什么不能定义静态属性和静态方法
2021-01-06 21:51:50根据成员内部类的定义: 首先生成外部类的实例对象 然后生成绑定到外部类实例对象的成员内部类实例对象 外部类实例对象的生成一定要先于成员内部类实例对象的生成 public class InnerClassDemo{ //对于final修饰... -
Javascript:ES6中新增class类中静态方法如何在类内部被调用
2020-12-04 09:47:40ES6中新增class类中静态方法如何在类内部被调用 -
内部类和枚举类
2021-02-27 14:57:02内部类可以定义在外部类的成员位置(与成员变量的位置相同)或局部位置(意思是,把类写在外部类的方法里面)。什么时候使用内部类 :一个具体的事物里面还有一个具体的事物。比如汽车中有发动机。1、成员内部类1.将内部... -
python中在实例方法内部调用同一类中另一个实例方法
2020-06-13 22:18:55#定义一个类a class a(): def __init__(self,input): #定义一个实例属性 self.height = input ... #定义另一个实例方法,该方法需要方法A中的返回值,则在方法B中这样调用 def B(self): print(a.A(self)) -
关于java成员内部类(普通内部类)在main方法中调用
2017-02-08 00:41:18main方法访问普通内部类的例子: //外部类test public class Test { //非静态的外部类成员变量 int num=1; /** * 普通内部类Person * */ class Person{ int age; } public static void main(String... -
详谈Java内部类(超详细代码示例)
2018-09-30 00:30:44内部类 废话不多上,先上图: -
java内部类为什么可以访问外部类属性方法
2018-09-25 16:21:18静态内部类不能访问外部类的属性方法,所以android开发过程中可以优化handler 其他内部类可以访问外部类,是因为持有外部类的引用。 成员内部类说明: 成员内部类拥有和外部类同名的成员变量或者方法时,会发生... -
python如何调用类中的方法
2020-11-24 12:30:45调用同一个类中的方法首先类中的方法在定义的时候需要先加参数self,例如:def SaveData(self,ip):print(ip)如果无self参数则不能在同一个类中调用(之前一直在这里犯错,警醒之)无self参数的情况下是可以在另一个... -
Python内部类,内部类调用外部类属性,方法
2018-12-17 10:07:04一 Python中内部类 class MyOuter: age=18 def __init__(self,name): self.name=name class MyInner: def __init__(self,inner_name): self.inner_name=inner_name out=MyOute... -
详解 Java 内部类
2018-09-04 00:17:56内部类在 Java 里面算是非常常见的一个功能了,在日常开发中我们肯定多多少少都用过,这里总结一下关于 Java 中内部类的相关知识点和一些使用内部类时需要注意的点。 从种类上说,内部类可以分为四类:普通内部类... -
java匿名内部类和lambda(匿名方法)
2019-07-28 13:05:21内部类分4种:成员内部类,静态内部类,局部内部类和匿名内部类。我们今天讨论的就是其中最常见的匿名内部类。从名称可以看出,就是没有名字的类,因为没有名字,所以总归和其它普通类有一些些区别: 类如果没有... -
内部类,局部内部类与匿名内部类创建对象方法
2018-08-03 20:37:00定义在A类中的B类就是内部类,B类在A类中的地位和其他成员相同,意思就是说可以相互调用 优点:通过内部类可以让java间接的实现多继承 创建内部类的对象 方法一 先获取内部类对象再调用方法 Outer out = ... -
java内部类之成员内部类、局部内部类和匿名内部类
2018-07-15 16:13:30一个类中包含另外一个类。 分类 1、成员内部类。 2、局部内部类(包含匿名内部类)。 成员内部类 定义格式: 修饰符 class 类名称 { 修饰符 class 类名称 { //... } //... } 注意: 内部类使用外部,...