我们了解了内部了的基本定义与分类,我们详细讲述了在是否存在名字这方面进行的分类:有名内部类和匿名内部类。
那么这篇文章就来探讨一下静态内部类与非静态内部类的区别。
按照是否有static修饰分为静态内部类和非静态内部类,有static修饰的为静态内部类,没有static修饰的为非静态内部类。
静态内部类
1.如果要定义一个静态内部类,只能直接定义在外部类中,不可以定义在方法或代码块中。
2.静态内部类仅能直接访问外部类的静态成员变量和方法。
3.如果想要调用非静态的成员变量和方法,可以通过创建外部类的对象间接使用。
public class OutClass {
private double weight=72;
public static void print(String name) {
System.out.println(name);
}
static class InClass{
{
double weight = new OutClass().weight;//由于weight是非静态的,所以在静态内部类中使用时必须先创建外部类对象
print("Tom");//由于print方法为静态方法,所以可以直接使用。
}
}
}
如代码所示,静态内部类InClass想要调用weight成员变量,那么他就必须要new OutClass()来调用weight。所谓的间接使用。
而由static修饰的print方法,静态内部类调用它就直接可以使用方法名来调用。
4.只有有名静态内部类中才允许有静态成员(静态属性、静态代码块和静态方法)。
非静态内部类是绝对不可以有静态成员的。
非静态内部类
1.如果要定义一个静态内部类,可以定义在方法或代码块中,也可以定义在外部类中。
注意,如果在方法或者代码块中定义,和局部变量一样,其使用范围从定义的位置开始到其所在直接语句块结束。
public class OutClass {
public static void main(String[] args) {
if(args!=null) {
class InClass{
}
}
InClass inClass = new InClass();//无法创建对象,因为内部类作用范围无法作用到这里
}
}
我们看到,InClass内部类就是在if语句中定义的,而创建对象的语句发生在if之外了,用法和成员变量一样,它的范围是达不到的。
2.非静态成员变量只能用对象去调用。
3.直接在类中定义的非静态内部类,创建对象时必须先创建外部类对象,这种创建外部类对象的方式,是隐式创建外部类对象的方式,这中的this指代的就是Body类创建的对象。
public class Body {
int age=12;
class Heart{
}
public void getHeart() {
System.out.println(this.age);
Heart heart = new Heart();
heart = this.new Heart();
}
4.直接在类中定义的非静态内部类,在静态方法中创建对象,必须“显式”创建外部类对象,必须new Body().去调用。
public class Body {
int age=12;
class Heart{
}
public static void getHeart(int a) {
System.out.println(new Body().age);
Heart heart = new Body().new Heart();
}
}
5.静态成员变量可以"直接"在非静态方法或代码块中使用。
因为静态的成员变量是在程序执行时就已经加载的,而非静态的方法和代码块都是在创建对象时才加载,所以非静态的方法和代码块都已经认识了早已加载完的静态的成员变量,所以自然可以调用。
即:静态的在类加载的时候处理:静态变量直接赋值 静态方法直接分配地址 静态代码块直接执行;非晶态的只能在创建对象时执行操作。变量 ——JVM对静态的操作比非静态的靠前。
6.局部变量不能由static修饰。