java 内部类的分类及用法区分

我们都知道,java说白了就是由一个一个类组成的,但是java的类又可以相互嵌套,甚至一个.java文件中最外层可以并行的定义多个类,这些类的关系是什么呢?

今天就来捋顺一下。

java中的类无非就是放在.java文件中,然后进过编译后生成.class文件。我们先来看下.java文件中有一个类的情况,这种情况比较好理解。

我们定义一个TextA的类,在java文件中它是这样存放的(如下图),同时.java文件名需要与TextA同名。


好了,这是我们最熟悉的一种情况。如果我们想在这个.java文件中包含多个类怎么办呢?

我们先来分析下,如果再加其他类,它可以放在什么位置,我总结了一共有三个位置,如图的位置1-3.

为了便于理解,我们主要从以下三个角度来分析,类放在这几个位置的不同:

问题1.可以用什么修饰符,即类名前边可以加public、private、protected,static中的那几个?

问题2.这些位置的类对外部类的访问权限是什么?是都可以访问,还是只能访问外部类的静态成员和方法?

问题3.在这些类中可不可以设置静态成员和静态方法?

好了,干货来了。

对于位置1:

问题1.可以用什么修饰符,即类名前边可以加public、private、protected,static中的那几个?

一个.java文件中,最外层的类最多只能有一个public的类,可以令其作为入口类执行(重写main方法)且.java文件名称需要与被public修饰的类相同。如果一个.java文件中的class都没有public修饰,那这个.java文件的类名就可以随便定义了。其他类不可以加任何其他修饰符。除这点区别之外,这些最外层的类在使用上没有任何其他区别,如果这个.java文件中有多个位置1的最外层类,经过编译之后,每个类都可以单独的生成.class文件,所以区别仅在编译之前。除了public之外,private、protected,static都不可以加。

问题2.这些位置的类对外部类的访问权限是什么?是都可以访问,还是只能访问外部类的静态成员和方法?

访问权限与两个独立的类互相访问相同。

问题3.在这些类中可不可以设置静态成员和静态方法?

静态成员和静态方法的设置与单独写一个.java,然后设置静态成员和静态方法相同。

总结一句话,位置1中放入的类,对这个程序的影响,仅仅在编译之前,编译之后,无区别。

对于位置2:

问题1.可以用什么修饰符,即类名前边可以加public、private、protected,static中的那几个?

位置2实际上是成员变量和方法并行放置的位置,所以这里定义的类具有与成员变量、成员方法相同的特性,可以用public、private、protected,static中的任何一个修饰。

通过加不加static进行分类,不加static时 ,为非静态成员内部类 ,加static为静态成员内部类

关于他们的区别,我们可以利用普通成员变量和静态成员变量的区别来理解。

非静态成员内部类

在TextA内部定义时,无论用public、private、protected哪种修饰符修饰,都能通过外部类的对象new出来

在TextA外部定义时,用public修饰符修饰能通过外部类的对象或者其子类对象new出来;用private修饰符修饰能不能通过外部类的对象new出来;用protected修饰符修饰,在包内能通过外部类的对象new出来,在包外不能访问。

静态成员内部类

在TextA内部定义时,无论用public、private、protected哪种修饰符修饰,都能直接使用

在TextA外部定义时,用public修饰符修饰能能直接使用,也通过外部类点出来;用private修饰符修饰不能直接使用,也不能通过外部类点出来;用protected修饰符修饰在包内能直接使用,也能通过外部类点出来,包外无法访问。

问题2.这些位置的类对外部类的访问权限是什么?是都可以访问,还是只能访问外部类的静态成员和方法?

非静态成员内部类:

对外部类的访问没有限制。

静态成员内部类:

可以访问外部类的静态成员和静态方法。

PS:道理就如同静态方法内部只能调用静态方法,使用静态变量一样。

问题3在这些类中可不可以设置静态成员和静态方法?

非静态成员内部类:

不可以,因为内部类必须在外部类加载之后才能加载,而设成静态的,就能在编译后直接加载了,与前边的加载顺序冲突。

静态成员内部类:

可以,因为类设置成了静态的,所以可以单独加载。设置静态成员和静态方法,不影响。

对于位置三:

可以把这里面定义的类理解为局部变量,我们暂且叫它局部内部类

问题1.可以用什么修饰符,即类名前边可以加public、private、protected,static中的那几个?

局部变量是不能用public、private、protected,static修饰的,public、private、protected,static只能用来修饰成员变量和成员方法,所以这个问题可以不用考虑了。

问题2.这些位置的类对外部类的访问权限是什么?是都可以访问,还是只能访问外部类的静态成员和方法?

还是把它作为局部变量来理解,它只能访问局部变量,和非静态的静态成员和方法。

PS:如果这个方法是静态的,那么就都可以访问了外部类的静态成员和方法。

问题3在这些类中可不可以设置静态成员和静态方法?

不可以,还是通过局部变量来理解,方法中存放的都是局部变量,不管方法是不是static的,局部变量都不可以被static修饰,因为static是在类加载的时候,提前分配内存的到方法区的,而这个方法中局部变量的是放在栈区的,这本身就与java的内存配置矛盾了。

不知不觉,我们已经讨论了四种类的用法:与原类并行的类、非静态成员内部类、静态成员内部类、局部内部类(都是非静态的)。

然而还不够完美,还有一种类,不能用位置去限定它来划分种类,它就是匿名内部类

我们先来捋一下什么交匿名内部类,顾名思义,就是没有名字的类,没有名字的类我们怎么使用呢?这里就必须要明确一点了,匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,或实现一个接口。然后重写接口或者父类的方法,用父类引用或者接口引用指向他。因为没有名字,他只能被定义好后,被接收它的那个对象使用,之后再也不能通过它来new其他的对象了,一般用在多线程里面,来new多线程。

下面依次回答上边的问题:

问题1.可以用什么修饰符,即类名前边可以加public、private、protected,static中的那几个?

因为匿名内部类不能单独的存在,无法修饰,只能修饰接收匿名内部类的对象。

问题2.这些位置的类对外部类的访问权限是什么?是都可以访问,还是只能访问外部类的静态成员和方法?

可以随便访问,但是访问局部变量时,局部变量必须加final关键字。愿意如下:

        是变量的作用域的问题,因为匿名内部类是出现在一个方法的内部的,如果它要访问这个方法的参数或者方法中定义的变量,则这些参数和变量必须被修饰为final。因为虽然匿名内部类在方法的内部,但实际编译的时候,内部类编译成Outer.Inner,这说明内部类所处的位置和外部类中的方法处在同一个等级上,外部类中的方法中的变量或参数只是方法的局部变量,这些变量或参数的作用域只在这个方法内部有效。因为编译的时候内部类和方法在同一级别上,所以方法中的变量或参数只有为final,内部类才可以引用。

问题3在这些类中可不可以设置静态成员和静态方法?

不可以,还是加载顺序的问题,非静态内部类必须等外部类加载完毕后才能加载(为什么?因为内部类要用外部类的数据),如果可以设静态成员和静态方法就能单独加载了,会打破这种限制。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一步一台阶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值