java内部类
1.静态块和实例块
(1.)
static 所修饰的方法或者数据成员不依赖于对象
static{
this.naem = “youbo”
this.age = 20
}
和实例块初始化
{
this.naem = “youbo”
this.sex = 20
}
class Person1 {
private int age;
private String name;
private static int count;
public static int getCount() {
return count;
}
public static void setCount(int count) {
Person1.count = count;
}
{
this.name = "youbo";
this.age = 20;
System.out.println("实例块初始化");
}
public Person1() {
System.out.println("构造函数");
}
static {//static所修饰的方法或者数据成员不依赖于对象
//count = 10;
System.out.println("静态块初始化");
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
public class Test1028001 {
public static void main(String[] args) {
Person1 p = new Person1();
System.out.println(p);
System.out.println("=========");
Person1 p1 = new Person1();
Person1.setCount(12);
System.out.println(Person1.getCount());
}
}
输出结果为:
静态块初始化
实例块初始化
构造函数
Person{age=20, name='youbo'}
=========
实例块初始化
构造函数
12
对象的初始化顺序(上面的代码)
先静态块初始化(当类里面有 实例成员 和 实例代码块时,同等级别的执行顺序按照他们的顺序来执行)
然后实例代码块初始化
再然后构造函数初始化
在=========之后输出的可以看出
不管多少个对象,静态代码块只初始化一次;
对于”static所修饰的方法或者数据成员不依赖于对象“这句话的理解,上面代码中,
private static int count; 定义的count是static实例成员,而在主函数中,调用它的getCount和setCount方法时候,用的是类名,而不能用对象名;
Person1.setCount(12);
System.out.println(Person1.getCount());
2.内部类
四种内部类:
① 实例内部类: 内部类没有使用static修饰.
② 静态内部类: 内部类使用了static修饰.
③ 匿名内部类
④ 本地内部类
1.实例内部类:
实例内部类(没有static修饰)
面试问题.
(1)实例内部类是否有额外的开销(有)
(2)实例内部类是否有拥有外部内的对象(有)
(3)实例内部类当中是否可以有静态数据成员(有)但是只能是在编译期间确定的值,可以 是static但是必须是final所修饰
特点:
1:创建实例内部类前,必须存在外部类对象,通过外部类对象创建内部类对象(当存在内部类对象时,一定存在外部类对象). Outter.Inner in = new Outter().new Inner();
2:实例内部类的内部类可以直接访问外部类成员.
3:外部类中不能直接访问内部类的成员,必须通过内部类的实例去访问.
4:实例内部类中不能定义静态成员,只能定义实例成员.
5:如果实例内部类和外部类存在同名的字段或方法person,那么在内部类中:
this.preson:表示访问内部类成员.
外部类.this.person:表示访问外部类成员.
class OuterPerson{
String name = "youbo-outer";
public int a1;
private int a2;
private static int a3;
{
a1 = 001;
a2 = 002;
a3 = 003;
}
public void ooxx(){
System.out.println(this.new InnerPerson().age);
}
//实例内部类
class InnerPerson{
int age = 20;
String name = "youbo-inner";
private int a3 = 100;
public int a5 = 10;
private static final int A4 = 100;
public void test(){
String name = "youbo-local";
System.out.println(name);//访问内部类方法中的的name//如果方法中没有,访问的是内部类的name
System.out.println(this.name);//访问内部类的name
System.out.println(OuterPerson.this.name);//访问外部类的name
}
public void test2(){
System.out.println(a1);
System.out.println(a2);
System.out.println(this.a3);
System.out.println(OuterPerson.this.a3);
System.out.println("InnerPerson().test2()");
}
}
}
public static void main(String[] args) {
OuterPerson oP = new OuterPerson();
//外部类名.内部类名 引用名 = 外部类对象.new 内部类();
OuterPerson.InnerPerson iP = oP.new InnerPerson();
iP.test();
System.out.println("-------------------");
iP.test2();
}
运行结果为:
youbo-local
youbo-inner
youbo-outer
-------------------
1
2
100
3
InnerPerson().test2()
可以看出 OuterPerson oP = new OuterPerson();
OuterPerson.InnerPerson iP = oP.new InnerPerson();
先生成一个外部对象名oP, 然后在通过 外部类名.内部类名 引用名 = 外部类对象.new 内部类(); 去生成引用名iP ,用iP去调用内部类中的方法test1和test2;
2.静态内部类
面试问题
1.静态内部类如何访问外部类的非静态数据成员(静态内部类可以直接访问外部类的静态成员,如果访问外部类的实例成员,必须通过外部类的实例去访问.)
2.静态内部类是否拥有外部类对对象( 不拥有:静态内部类的实例不会自动持有外部类的特定实例的引用,在创建内部类的实例时,不必创建外部类的实例)
1):静态内部类在创建内部类的实例时,不必创建外部类的实例.
2):静态内部类可以直接访问外部类的静态成员,如果访问外部类的实例成员,必须通过外部类的实例去访问.
class OuterPerson1{
public int a1;
private int a2;
private static int a3;
public OuterPerson1(){
System.out.println("OuterPerson1()");
}
static class InnerPerson1{
public int a4 = 1;
OuterPerson1 out1;
public InnerPerson1(OuterPerson1 out1) {
this.out1 = out1;
System.out.println("InnerPerson1()");
}
public void test(){
System.out.println(a3);
System.out.println(a4);
System.out.println(out1.a2);
System.out.println(new OuterPerson1().a1);
System.out.println("InnerPerson().test()");
}
}
}
public static void main(String[] args) {
OuterPerson1 oP1 = new OuterPerson1();
System.out.println("=======");
//外部类名.内部类名 引用名 = 外部类对象.new 内部类();
OuterPerson1.InnerPerson1 iP1 = new OuterPerson1.InnerPerson1(oP1);
System.out.println("-------------------");
iP1.test();
}
运行结果为:
OuterPerson1()
=======
InnerPerson1()
-------------------
0
4
0
OuterPerson1()
0
InnerPerson().test()
可以看出,先调用外部类,创建对象 op1,然后在调用外部类名.内部类名 引用名 = 外部类对象.new 内部类();创建内部对象IP1,
在tset中new OuterPerson1().a1 时候,又调用了外部类;
3.匿名内部类
匿名内部类,是一个没有名称的局部内部类,适合只使用一次的类。
class OuterPerson3{
public void sayHello() {
System.out.println("hello");
}
}
public static void test(OuterPerson3 out3) {
out3.sayHello();
}
public static void main(String[] args) {
new OuterPerson3() {
public void sayHello() {
System.out.println("main : hello");
}
}.sayHello();
test(new OuterPerson3());
}
}
运行结果为:
main : hello
hello