网站首页 > 精选教程 正文
什么是内部类:
一个类内部除了有属性和方法,还可以有其他类,内部类也可以在方法或代码块中。 (往下会代码示例)
可以简单的理解为花括号里 { } 里面再定义一个类,那么这个类就称为:内部类。 因为理论上内部类可以在类任意位置,所以代码块也好,普通方法也可以。
内部类的作用:
1.增强封装,把内部类放在外部类当中,不允许其它类访问这个内部类。
2.增加了代码一个维护性,不涉及到其他类。
3.内部类可以直接访问外部类当中的成员。
内部类分为四种:
- 实例内部类:直接定义在类当中的一个类,在类前面没有任何一个修饰符。
- 静态内部类:在内部类前面加上一个static。
- 局部内部类:定义在方法当中的内部类。
- 匿名内部类:属于局部的一种特殊情况。
实例内部类
//外部类
//外部类
class Outer {
String str = "一颗剽悍的种子";
//内部类
class Inner{
void fun() {
System.out.println(str);
}
}
}
public class Test2{
public static void main(String[] args) {
Outer out = new Outer();
//实例内部类
out.new Inner().fun();
}
}
运行结果:
上面代码示例有个细节:就是我们提到过的内部类的作用, 内部类可以访问外部类的成员。
实例化内部类的格式:
new 外部类().new 内部类 ();
代码本身很简单,只要理解类的语法和对象实例化方式就可以了,了解它的底层才有趣,创建内部类的时候发生了什么? 在创建内部类的时候,会有一个外部类的引用。
我们可以用代码编译后的class文件通过我们的反编译工具来看。
class Outer$Inner
{
final Outer this$0;
void fun()
{
System.out.println(str);
}
Outer$Inner()
{
this$0 = Outer.this;
super();
}
}
从上面的代码可以看到,内部类当中除了有自己的引用,还有外部类的引用。在堆中相当于外部类有一个地址,内部类有两个地址,一个是自己内部类的,一个是指向外部类的地址。
静态内部类
有接触过Java 静态这个知识点的小伙伴应该都知道,谈到静态无非就是对static关键字的理解和运用,这么说你可能会好懂一些。
说得更直接点就是内部类前面加上一个 static 就是静态内部类。
//外部类
class Outer {
static String str = "一颗剽悍的种子";
//静态内部类
static class Inner{
void fun() {
System.out.println(str);
}
}
}
public class Test2{
public static void main(String[] args) {
new Outer.Inner().fun();;
}
}
运行结果
注意点:可以看到上面成员也是用static声明静态,是因为声明static无法直接调用非static变量或方法。
为什么?
我们都知道static是最先执行,在加载字节码就会自动调用,而且在主方法main之前,比构造方法早,此时非static属性和方法还没有完成初始化呢。
还有与上面非 static 定义内部类有两点不同:
1.静态内部类的创建格式不需要实例化,具体格式如下:
new 外部类(). 内部类 ();
2.静态内部类当中没有外部类的引用。
为什么?
因为加上static 静态内部类是属于外部类的,上面所说也可以看出它没有用new 而是通过 .类的方式。
还是通过我们的反编译查看class文件,有码有真相。
static class Outer$Inner
{
void fun()
{
System.out.println(Outer.str);
}
Outer$Inner()
{
}
}
局部内部类
开头说什么是内部类当中,有说到内部类不仅可以定义在外部类当中,也可以定义在方法当中,而定义在方法当中的类称为局部内部类
//外部类
class Outer {
void fun_1() {
String name = "一颗剽悍的种子";
class Inner{
void fun_2() {
System.out.print(name);
}
}
Inner in = new Inner();
in.fun_2();
}
}
public class Test2{
public static void main(String[] args) {
new Outer().fun_1();
}
}
运行结果
局部内部类有什么局限性呢?
1.局部内部类只能在定义方法中使用。 可以看到代码示例,在方法中创建内部类并且调用内部类里的方法,后续实例化只要调用外部类里的 fun_1 方法就可以。
2.不能使用 public、protected、private 修饰 。 这一条是对应第一条的,你想想,你已经在方法中创建了,只在方法中使用,你还用这些权限干嘛 ???
3.局部类当中不能使用static变量。 上面静态内部类时说过,static是属于外部类的,所以在方法里的内部类定义static变量会报错。
除了局部内部类的局限性,还可以看到在代码实例中,内部类是可以直接使用方法中的变量的。
(在jdk1.7之前内部类想访问方法中的变量是需要加上final的,我们知道final是用来声明常量的,fianl需要设置好值而且不能修改。)
jdk1.8版本之后不需要,正好我的jdk1.8 所以就不用加final了,但是真实情况下,通过反编译工具看class文件会发现编译时已经帮我们自动加上了。
(你会发现随着语言的发展,让你更易于开发的同时,你离本质也更加的遥远)
class Outer$1Inner
{
final Outer this$0;
private final String val$name;
void fun_2()
{
System.out.print(val$name);
}
Outer$1Inner()
{
this$0 = final_outer;
val$name = String.this;
super();
}
}
到这里可能有小伙伴会问,为啥内部声明变量需要加上final,这里就不展开了,因为涉及到 final 在方法区以及代码运行后的堆栈关系,下次有机会再写一篇。
匿名内部类
根据字面意思就知道没有命名的内部类,那么匿名内部类就是没有构造器的,因为我们都知道类的构造器需要跟类同样的命名。
new 父类 或 接口
上面围绕四种内部类展开,实例内部类,静态内部类、局部内部类、匿名内部类,因为匿名内部类的应用是比较少,所以简单的谈谈就没有代码示例,等有用到,而且好的例子,可以再单独写一篇滴。
作者:CSDN博主「一颗剽悍的种子」
原文链接:https://blog.csdn.net/A_hxy/article/details/106985170
- 上一篇: Java内部类解析,你知道多少?
- 下一篇: java的内部类大家用过没有
猜你喜欢
- 2024-11-24 永远不要使用双花括号初始化实例,除非你想OOM
- 2024-11-24 java中的匿名内部类总结
- 2024-11-24 Java Nested Classes(内部类~英文技术文档翻译)
- 2024-11-24 带你深入学习java内部类_匿名类,细到不能再细
- 2024-11-24 为何要在Java中使用静态类?
- 2024-11-24 68、下面的内部类在哪里new不会编译出错
- 2024-11-24 面向对象高级特性内部类
- 2024-11-24 Java局部内部类
- 2024-11-24 Java 内部类和异常类(详细版)
- 2024-11-24 IntelliJ IDEA 2022.2.1 beta 发布,新增支持 Java 18
你 发表评论:
欢迎- 04-11Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- 04-11Java中你知道几种从字符串中找指定的字符的数量
- 04-11探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- 04-11Python字符串详解与示例(python字符串的常见操作)
- 04-11java正则-取出指定字符串之间的内容
- 04-11String s1 = new String("abc");这句话创建了几个字符串对象?
- 04-11java判断字符串中是否包含某个字符
- 04-11关于java开发中正确的发牌逻辑编写规范
- 最近发表
-
- Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- Java中你知道几种从字符串中找指定的字符的数量
- 探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- Python字符串详解与示例(python字符串的常见操作)
- java正则-取出指定字符串之间的内容
- String s1 = new String("abc");这句话创建了几个字符串对象?
- java判断字符串中是否包含某个字符
- 关于java开发中正确的发牌逻辑编写规范
- windows、linux如何后台运行jar(并且显示进程名)
- 腾讯大佬私人收藏,GitHub上最受欢迎的100个JAVA库,值得学习
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)