内部类:定义在类结构中的另一个类:
类中的定义的成员:字段、方法、内部类
为什么使用内部类?
- 增强封装,把内部类隐藏在外部类之内,不许其他类访问该类。
- 内部类能提高代码的可读性和可维护性,把小型类嵌入到外部类中结构上代码更靠近。
- 内部类可以直接访问外部类的成员。
package com.test;
//双向链表
public class LinkledList {//第一个节点private Node first;//最后一个节点private Node last;//火车的车厢是在火车的内部class Node{private Node prev;//上一个节点private Node next;//下一个节点private Object ele;//当前节点存储的数据}
}
外部类的访问修饰符:要么public要么缺省。
内部类看做是外部类的一个成员,那么内部类可以使用public/缺省\protected\private修饰,还可以是static修饰。
内部类分为四种:
- 实例内部类:内部类没有使用static修饰
- 静态内部类:内部类使用了static修饰
- 局部内部类:在方法中定义的内部类
- 匿名内部类适合于使用一次使用的类,属于局部内部类的特殊情况。
对于每个内部类来说:java编译器会生成独立的.class文件。 - 成员内部类:外部类$内部类名称
- 局部内部类:外部类名$数字&内部类名称
- 匿名内部类:外部类名¥数字
实例内部类:没有static修饰内部类,说明内部类属于外部类的对象
特点:
- 创建实例内部类前,必须存在外部类对象,通过外部类对象创建内部类对象(当存在内部类对象时,一定存在外部类对象)。
package com.test;class Outer{String name="ok";class Inner{void print(){System.out.println(name);}}
}
public class test1{public static void main(String[] args){Outer out=new Outer();out.new Inner().print();;//通过外部类对uter.Inner in=out.new Inner();}
}
- 实例内部类的实例自动持有外部类的实例的引用,内部类可以直接访问外部类成员。
- 外部类中不能够直接访问内部类的成员,必须通过内部类的实例去访问。
class Outer{
String name="外部类";
void OuterPrint(){
System.out.println(new Inner().str);
}
class Inner{
private String str="内部类";
void print(){
System.out.println(name);
}
}
}
“` - 如果实例内部类和外部类存在同名的字段和方法abc,在内部类中:this.abc:表示
访问内部类成员,反之亦然。
静态内部类:
使用static修饰的内部类。
特点:
- 静态内部类的实例不会自动持有外部类的特定实例的引用,在创建内部类的实例时,不必创建外部类的实例。
package com.test;class Outer{static String name="外部类";static class Inner{private static final String str="内部类";void print(){System.out.println(name);}}
}
public class test1{public static void main(String[] args){//不必new Outer().new Inner(),因此不必创建外部类的实例new Outer.Inner().print();}
}
2.静态内部类中可以直接访问外部类的静态成员,如果访问外部类的实例成员,必须通过外部类的实例去访问。
class Outer{static String str="外部类";String s="非静态";static class Inner{static void print(){System.out.println(str);}}
}
3.在静态内部类中可以定义静态成员和实例成员。
4.测试类可以通过完整的类名直接访问静态内部类的静态方法。
package com.test;class Outer{static class Inner{static void print(){System.out.println("静态内部类");}}
}
public class test1{public static void main(String[] args){//不必new Outer().new Inner(),因此不必创建外部类的实例Outer.Inner.print();}
}
局部内部类(没啥用):
在方法中的定义的内部类,其可见范围是当前方法和局部变量是同一个级别。
public class test1{public static void main(String[] args){class Inner{void print(){System.out.println("内部类");}}}
}
1.不能使用public、private、protected和static修饰符。
2.局部内部类只能在当前方法中使用。
3.局部内部类和实力内部类一样,不能包含静态成员。
4.局部内部类和实力内部类,可以访问外部类的所有成员。
5.
局部内部类访问的局部变量必须使用final修饰(在java中自动隐式加上final,但是依然是常量不能改变值)。
上述代码报错!!!
package com.test;public class test1{public static void main(String[] args){final int num=17;class Inner{void print(){System.out.println(num);}}new Inner().print();}
}
java 中变量存储位置的区别
1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制.
2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中。)
3. 堆:存放所有new出来的对象。
4. 静态域:存放静态成员(static定义的)
5. 常量池:存放字符串常量和基本类型常量(public static final)。
6. 非RAM存储:硬盘等永久存储空间
如果用final修饰变量就是常量存放在常量池中,当方法被销毁后对象仍然可以调用。
匿名内部类:是一个没有名称的局部内部类,适合只使用依次的类,是特殊的局部内部类,满足局部内部类特征。