Java嵌套类
程序员文章站
2022-06-01 11:34:29
...
目录
嵌套类概述
我们通常会将静态嵌套类也误称为内部类,实际上内部类所指的是非静态嵌套内部类。在编程中我们通过使用嵌套类通常可以实现更细粒度的控制,避免过多的内定义。但是嵌套类本身的语言设计过于复杂,较难学习和使用,一定程度上违背了Java语言本省的初衷。
代码示例与嵌套类分类的特点概述
-
局部内部类
public class Outer2 {
private String news1 ="Outer2的私有成员";
static String newsStatic ="Outer2的静态成员变量";
static int outer2_i =0;
public static void meathStatic(){
// 局部内部类可以定义在代码块内,(亦包括循环体中),多定义的类只在代码块中起作用
final int[] meath_i = {0};
for (int i = 0; i < 5; i++) {
final int[] for_i = {0};
// 可以实现正常的继承父类或者说是接口
class Inner1 extends OtherTest{
// 非静态的类,不能包含静态成员(变量和方法),除了常量
public static final int temp =3;
int inner1_i =0;
String inner1Alias;
// 可以正常的使用构造函数
public Inner1(String name){
this.inner1Alias =name;
}
public void traverse_all_i(){
// 可以访问外围类包围的成员,但是如果是定义在静态方法体中那就只能防卫外
// 围类的静态成员变量,即不能访问news1,只能访问newsStatic,如果要是
// meathStatic不是静态的话那么在这里就是可以访问news1的
System.out.println("通过构造函数给Inner1的昵称:"+inner1Alias+"----"+newsStatic+"outer2_i:"+(++outer2_i)+"; meath_i[0]:"+(++meath_i[0])+"; for_i:"+(for_i[0])+"; inner1_i:"+(++inner1_i));
}
}
Inner1 inner1 =new Inner1("Inner1_1号");
inner1.traverse_all_i();
System.out.println(inner1.getClass().getName()+" "+inner1);
}
// 内部类Inner1我们是定义在了for循环体内,所以Inner1只能够在for的{}中起作用,在这里我们
// 访问不到的
}
}
通过Outer2.meathStatic();运行后的结果如图所示,虽然具有相同的名称但是我们可以看到每循环一次都是有不同的对象创建。
在程序中我们试图通过++的运算符来对处在不同层级的变量实现一个累加的效果,从而观察出,在运行的过程中对象被创建了几次。当我们在内部类中使用变量时位于方法体、循环体中变量时出现报错要求使用最终类型。在这里我是通过系统自动解决错误的时候,系统把原来的int for_i =0 变成了常量数组的形式 final int[] for_i = {0},这时候数组for_i虽然是常量的形式,但是单个变量任然是可以进行值运算的。
-
匿名内部类
匿名内部类与局部内部类是相似的没有太大的差别,差别主要表现在匿名内部类是没有名字的,也不可能被第二次创建使用,匿名内部类的的代码表现的更加简洁干净。
public class Outer1 {
private String name = "abc";
//匿名内部类
//public static void f1()
public void f1()
{
final String name = "def";
Runnable r = new Runnable() {
//匿名内部类不能定义静态变量,除非是常量
public final static int a = 5;
//public static int b = 3;
//String name = "ghi";
@Override
public void run(){
System.out.println("hello " + name);
//屏蔽外部方法的临时变量
//https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html#shadowing
}
//静态方法不能在匿名内部类定义
// public static void f2() {
// }
};
new Thread(r).start();
System.out.println(r.getClass().getName());
Runnable r2 = new Runnable() {
@Override
public void run(){
//System.out.println("hello " + this.name);
}
};
new Thread(r2).start();
System.out.println(r2.getClass().getName());
}
}
编译过后内部类是会单独生成一个class文件的:
-
普通内部类
public class OuterClass2 {
protected class Inner2{
String name;
public Inner2(String name){
this.name =name;
}
public void hello(){
System.out.println("Hello,"+name);
}
}
}
public class OuterClass2Test {
public static void main(String[] args) {
// 需要先定义外部类才能再定义内部类,内部类是需要依赖于内部类的
OuterClass2 outerClass2 =new OuterClass2();
OuterClass2.Inner2 inner2 =outerClass2.new OuterClass2.Inner2("LiuMengLei");
inner2.hello();
}
}
-
静态嵌套类
public class OuterClass1 {
protected static class Inner1{
String name;
public Inner1(String name){
this.name =name;
}
public void hello(){
System.out.println("Hello,"+name);
}
}
}
public class OuterClass1Test {
public static void main(String[] args) {
// 可以直接单独使用只不过是需要外部类的一个调用
OuterClass1.Inner1 inner1 =new OuterClass1.Inner1("LiuMengLei");
inner1.hello();
}
}
嵌套类的对比与应用
public class ShadowTest2 {
public int x = 0;
public void f1()
{
int x = 20; //局部内部类无法访问得到!
class FirstLevel {
public int x = 1;
void methodInFirstLevel(int x) {
System.out.println("x = " + x); //第12行
System.out.println("this.x = " + this.x); // 第10行
System.out.println("ShadowTest.this.x = " + ShadowTest2.this.x); //第4行
}
}
FirstLevel obj = new FirstLevel();
obj.methodInFirstLevel(10);
}
public static void main(String... args) {
ShadowTest2 st = new ShadowTest2();
st.f1();;
}
}
上一篇: Python基础复习案例4:阿姆斯特朗数以及python代码缩进管理
下一篇: C++类的初识