《JAVASE系列》类和对象篇:代码块与内部类
文章目录
前言:
本章主要学习:
1.实例代码块与静态代码块
2.封装之内部类
参考书籍:《java核心卷1》
你若盛开,清风自来。
1.代码块
代码块有多种:
- 普通代码块
- 实例代码块
- 静态代码块
- 同步代码块
本节只介绍实例代码块与静态代码块
1.1 实例代码块
实例代码块:定义在类中的代码块(不加修饰符)
例如:
class A {
public A(){
System.out.println("A的构造方法");
}
{
System.out.println("A的实例代码块");
}
}
public class test{
public static void main(String[] args) {
A a = new A();
}
}
由上面的代码运行结果:
可以得出结论:
实例代码块的优先级高于构造方法,再构造方法执行前先执行实例代码块。
从字节码的角度来说:是把实例代码块的内容拷贝到了构造方法之前。所以实例代码块会优先执行于构造方法。
实例代码块一般用于初始化成员变量。
class A {
private int a;
private int b;
private int c;
{
this.a = 10;
this.b = 20;
this.c = 30;
}
}
1.2 静态代码块
使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。
静态代码块不能初始化非静态成员。
优先级问题:
class A {
private static int a1;
private static int b1;
private static int c1;
private int a;
private int b;
private int c;
public A(){
System.out.println("构造方法");
}
{
this.a = 10;
this.b = 20;
this.c = 30;
System.out.println("实例代码块");
}
static {
a1 = 10;
b1 = 20;
c1 = 30;
System.out.println("静态代码块");
}
}
public class test{
public static void main(String[] args) {
A a = new A();
System.out.println("=============");
A b = new A();
}
}
运行结果:
我们可以得出结论:
- 静态代码块的优先级最高,其次是实例代码块,最后才是构造方法。
- 当多个对线执行时,静态代码块只执行一次。
- 如果有多个静态代码块,则根据定义的顺序来执行
2.内部类
在 Java 中,可以将一个类定义在另一个类或者一个方法的内部,
前者称为内部类,后者称为外部类。
内部类也是封装的一种体现。
public class Outclass {
class Innerclass{
}
}
// OutClass是外部类
// InnerClass是内部类
2.1 内部类的分类
public class OutClass {
// 成员位置定义:未被static修饰 ---> 普通内部类
public class InnerClass1{
}
// 成员位置定义:被static修饰 ---> 静态内部类
static class InnerClass2{
}
public void method(){
// 方法中也可以定义内部类 ---> 局部内部类
class InnerClass5{
}
}
}
根据内部类定义的位置不同,一般可以分为以下几种形式:
- 普通内部类
- 静态内部类
- 局部内部类(较少用到)
- 匿名内部类(与多线程有关)
本章主要讲解普通内部类和静态内部类。
2.2 如何实例化 实例内部类 对象
两种方式:
第一种:先创建外部类再创建内部类 (比较容易理解)
class Outclass{
private int a;
private int b;
private int c;
class Innerclass{
public Innerclass(){
System.out.println("普通内部类");
}
}
}
public class test{
public static void main(String[] args) {
Outclass outclass = new Outclass();
//先创建外部类
Outclass.Innerclass innerclass= outclass.new Innerclass();
//再创建内部类
// 外部类名.内部类名 对象名 = 外部类对象.new 内部类名();
}
}
第二种:直接创建
public class test{
public static void main(String[] args) {
OutClass.InnerClass innerClass1 = new OutClass().new InnerClass();
//外部类名.内部类名 对象名 = new 外部类类名().new 内部类名();
}
}
2.3 实例内部类知识点:
-
实例内部类中定义静态成员变量的注意点
所以实例代码块中是不能定义静态变量的,如果要定义,必须将该静态变量用final修饰。
-
实例内部类中,成员变量与外部类成员变量重名时。
class Outclass{ private int a; private int b; private int c; public Outclass(){ this.a = 100; } class Innerclass{ private int a; public Innerclass(){ this.a = 10;//这里的this是内部类对象的引用 } public void print(){ System.out.println(this.a); System.out.println(Outclass.this.a); //Outclass.this 在内部类中调用外部类对象的引用 } public static final int data = 60; } }
运行结果:
结论:
-
优先使用自己的成员变量。
-
可以通过 外部类名.this 访问外部类的成员变量
实例内部类不仅包含了当前对象的this也包含了外部类的this。
-
-
实例内部类不能包含静态方法
-
外部类中不能直接访问实例内部类的成员,如果要访问需要先创建内部类的对象
2.4 静态内部类知识点:
class Outclass{
static class Innerclass{
}
}
-
如何实例化静态内部类对象:
由于实例化静态内部类不依赖于外部类对象,所以:
public class test{ public static void main(String[] args) { Outclass.Innerclass innerclass = new Outclass.Innerclass(); } }
-
在静态内部类中,只能访问外部类的静态成员,如果要访问普通成员变量,则需要实例化外部类对象。
直接实例化外部类对象
class Outclass{ private static int m; private static int n; private int a; private int b; private int c; public Outclass(){ this.a = 100; } static class Innerclass1{ private int d1; private int d2; private int d3; Outclass outclass = new Outclass(); //实例化对象 public void func(){ m = 10; outclass.a = 10; System.out.println("静态内部类"); } } }
传入实例化外部类对象
class Outclass{ private static int m; private static int n; private int a; private int b; private int c; public Outclass(){ this.a = 100; } static class Innerclass1{ private int d1; private int d2; private int d3; Outclass outclass = new Outclass(); //null空对象用来接收 public Innerclass1(Outclass out){ //构造方法接收对象 outclass = out; } public void func(){ m = 10; outclass.a = 10; System.out.println("静态内部类"); } } } public class test{ public static void main(String[] args) { Outclass outclass = new Outclass(); Outclass.Innerclass1 innerclass = new Outclass.Innerclass1(outclass); innerclass.func(); } }
静态内部类与静态变量/方法都是外部类的特征,不依赖于对象,所以静态内部类可以访问静态的外部类属性,而静态内部类访问外部类的普通成员/方法。则需要实例化外部类对象
个人理解(如有错误请指正!)
2.5 了解局部代码块
定义在外部类的方法体或者{}中,该种内部类只能在其定义的位置使用,一般使用的非常少,此处简单了解下语法格式。
public class OutClass {
int a = 10;
public void method(){
int b = 10;
// 局部内部类:定义在方法体内部
// 不能被public、static等访问限定符修饰
class InnerClass{
public void methodInnerClass(){
System.out.println(a);
System.out.println(b);
}
}
// 只能在该方法体内部使用,其他位置都不能用
InnerClass innerClass = new InnerClass();
innerClass.methodInnerClass();
}
public static void main(String[] args) {
}
}
注意:
- 局部内部类只能在所定义的方法体内部使用
- 不能被public、static等修饰符修饰
- 几乎不会使用
总结:
学习完需要能回答出以下问题:
- 代码块以及构造方法的优先级
- 静态代码块可以初始化非静态成员吗?为什么?
- 示例内部类中可以有静态方法吗?
- 实例内部类中如何访问外部类的普通成员?
- 静态内部类中如何访问外部类的普通成员?
感谢阅读!
与君共勉!