文章目录
- 注意一:实例内部类里面不能有static修饰的成员变量,内部类就相当于一个普通的成员,跟成员方法/变量一样;
- 注意二:静态方法里面不可以有this
- 注意三:内部类里面可以有static final 修饰的常量 ,但方法里面连static final 修饰的常量 也没有
- 注意四:实例内部类中调用外部类的变量和方法
- 注意五:外部类不可以直接访问实例内部类中的成员,如果非要访问,要先创建内部类对象。
- 注意六:静态内部类里面只能访问外部类中的静态方法与变量
- 注意七:静态内部类里面只能访问外部类中的静态方法与变量,原因是外部类中的非静态方法与变量是依赖于对象的,所以非要访问外部类中非静态的变量与方法,要通过对象的引用来调用。
注意一:实例内部类里面不能有static修饰的成员变量,内部类就相当于一个普通的成员,跟成员方法/变量一样;
跟成员方法里面不可以有static修饰的局部变量一样
public class OutClass {
public int date;
String date2;
public static double date3;
public void func(){
static int i = 0; // A error
System.out.println("func");
}
public static void main(String[] args) {
static int k = 0; // B error
}
class IntClass {
public int date4;
String date5;
public static double date6; // C error
public void func2(){
System.out.println("func2");
}
}
}
在非静态内部类里面是不可以有 static 静态变量的,因为静态的方法,非静态的方法 以及静态成员变量 在类加载阶段就已经被加载到方
法区了,静态的成员变量是在方法区开辟内存,而静态方法 非静态方法只是把加载的信息放在了方法区,但并没有给他分配内存,而是
等对象创建后,调用相应的方法的时候才会在虚拟机栈上开辟方法的栈帧,来存储方法内的局部变量。而此时对象还没有被创建,所以就
会矛盾,因为栈帧都还没有就把栈帧内部的局部变量存储在方法区了,所以这是错误的。栈帧内部的局部变量只能存储在虚拟机栈上。
所以方法(静态/非静态)里面绝对不可以有静态变量。非静态内部类里面是不能有静态变量。
注意二:静态方法里面不可以有this
静态方法是不依赖于对象的,直接通过类名来调用,
非静态方法是依赖于对象的,通过对象的引用来调用,要让非静态方法知道是哪个对象来调用它
public void setTest3(Test3 this,String name,int age){
this.name = name;
this.age = age;
}
public void show(Test3 this){
System.out.println(this.name + " " + this.age);
}
其实非静态的方法参数列表里面有一个默认的 this ,用于接收对象的引用 ,要让方法知道是哪个对象来调用它。
其实非静态的方法里面的this 全都是都应对象的引用。
而静态的方法不依赖于对象,参数列表里面没有默认的 this,无法用来接受对象的引用,所以方法内部压根不知道this是个啥。
注意三:内部类里面可以有static final 修饰的常量 ,但方法里面连static final 修饰的常量 也没有
public class OutClass {
public int date = 1;
String date2 = " 2 ";
public void func(){
static final int i = 0; //error
System.out.println("func");
}
class IntClass {
public int date4 = 4;
String date5 = " 5 ";
public static final double date6 = 6.0; //right
public void func2()
{
public static final double date7 = 7.0; //error
System.out.println(OutClass.this.date);
System.out.println("func2");
}
}
public static void main(String[] args) {
//实例内部类的创建方法
OutClass outClass = new OutClass();
OutClass.IntClass intClass = outClass.new IntClass();
}
}
实例内部类的创建方法:
OutClass outClass = new OutClass(); //先创建外部类对象
OutClass.InClass inClass = outClass.new InClass();
//Scanner scanner = new Scanner ();
注意四:实例内部类中调用外部类的变量和方法
public class OutClass {
public int date = 1;
String date2 = " 2 ";
public int func(){
System.out.println("func");
return 1;
}
class IntClass {
int date = 10;
public static final double date6 = 6.0;
public void func3() //实例内部类可以访问任何外部类的方法与变量
{
System.out.println(date2);
System.out.println(func());
}
public void func2()
{
System.out.println(OutClass.this.func()); // 调用外部类中的方法
System.out.println(OutClass.this.date; // 调用外部类中的变量
System.out.println("func2");
}
}
public static void main(String[] args) {
//实例内部类的创建方法
OutClass outClass = new OutClass();
OutClass.IntClass intClass = outClass.new IntClass();
intClass.func2();
}
}
//func
//1
//1
//func2
当实力内部类与外部类的方法名或变量名相同时,实例内部类中调用外部类的变量和方法。
注意: 实例内部类的非静态方法中包含了一个指向外部类对象的引用
// OutClass.this.外部类方法名
// OutClass.this.外部类变量名
内部类加上private 在类外面就不能访问了,连在类外面创建一个内部类都不行
注意:实例内部类中没有静态的变量与方法,有静态常量。
实例内部类,经过编译之后会生成独立的字节码文件,命名格式为:外部类名称$内部类名称
一个类对应一个字节码文件
注意五:外部类不可以直接访问实例内部类中的成员,如果非要访问,要先创建内部类对象。
package demo;
public class OutClass {
public int date = 1;
String date2 = " 2 ";
public int func(){
System.out.println("func");
return 1;
}
public void test(IntClass intClass){
System.out.println(intClass.date);
}
private class IntClass {
int date = 10;
public static final double date6 = 6.0;
public void func2()
{
System.out.println(OutClass.this.func()); // 调用外部类中的方法
System.out.println(OutClass.this.date); // 调用外部类中的变量
System.out.println("func2");
}
}
public static void main(String[] args) {
//实例内部类的创建方法
OutClass outClass = new OutClass();
OutClass.IntClass intClass = outClass.new IntClass();
//intClass.func2();
outClass.test(intClass);
}
}
外部类访问内部类中的方法与变量,可以将创建好的内部类的引用 传给 外部类方法,进而访问内部类
也可以直接在外部类方法中创建内部类对象进而访问内部类。
注意六:静态内部类里面只能访问外部类中的静态方法与变量
public class OutClass {
private int a;
static int b;
public void methodA(){
a = 10;
System.out.println(a);
}
public static void methodB(){
System.out.println(b);
}
// 静态内部类:被static修饰的成员内部类
static class InnerClass{
public void methodInner(){
// 在内部类中只能访问外部类的静态成员
// a = 100; // 编译失败,因为a不是类成员变量
b =200;
// methodA(); // 编译失败,因为methodB()不是类成员方法
methodB();
}
}
public static void main(String[] args) {
// 静态内部类对象创建 & 成员访问
OutClass.InnerClass innerClass = new OutClass.InnerClass();
innerClass.methodInner();
}
}
注意:
实例内部类的非静态方法中包含了一个指向外部类对象的引用,但是静态内部类里面没有,所以一下方法在静态内部类中完全是错误的
// OutClass.this.外部类方法名
// OutClass.this.外部类变量名
注意
静态内部类的创建
OutClass.InClass inClass = new OutClass.InClass();
// Scanner scanner = new Scanner();
注意七:静态内部类里面只能访问外部类中的静态方法与变量,原因是外部类中的非静态方法与变量是依赖于对象的,所以非要访问外部类中非静态的变量与方法,要通过对象的引用来调用。
方法一:
package demo;
public class OutClass {
public static int date = 1;
String date2 = " 2 ";
public int func(){
System.out.println("func");
return 1;
}
static class IntClass {
int date = 10;
public static final double date6 = 6.0;
public void func3()
{
OutClass outClass = new OutClass(); //直接在内部类里面创建
System.out.println(outClass.date2);
System.out.println(outClass.func());
func2();
}
public void func2(){
System.out.println(date);
}
}
public static void main(String[] args) {
OutClass.IntClass intClass = new OutClass.IntClass();
intClass.func3();
}
}
方法二:
package demo;
public class OutClass {
public static int date = 1;
String date2 = " 2 ";
public int func(){
System.out.println("func");
return 1;
}
static class IntClass {
int date = 10;
public static final double date6 = 6.0;
public void func3(OutClass outClass)
{
System.out.println(outClass.date2);
System.out.println(outClass.func());
func2();
}
public void func2(){
System.out.println(date);
}
}
public static void main(String[] args) {
OutClass.IntClass intClass = new OutClass.IntClass();
OutClass outClass = new OutClass();
intClass.func3(outClass); // 直接穿外部对象的引用
}
}
外部类像访问静态内部类中的变量/方法 也需要对象的引用。
package demo;
public class OutClass {
public static int date = 1;
String date2 = " 2 ";
public int func(IntClass intClass){
System.out.println(intClass.date);
return 1;
}
static class IntClass {
int date = 10;
public static final double date6 = 6.0;
public void func3(OutClass outClass,IntClass intClass)
{
System.out.println(outClass.date2);
System.out.println(outClass.func(intClass));
func2();
}
public void func2(){
System.out.println(date);
}
}
public static void main(String[] args) {
OutClass.IntClass intClass = new OutClass.IntClass();
OutClass outClass = new OutClass();
intClass.func3(outClass , intClass);
outClass.func(intClass);
}
}
总结:
静态内部类可以看成一个静态方法, 静态方法可以自由访问类中静态变量与方法,但是想访问类中的非静态的变量与方法,就需要借助
对象的引用,因为静态的方法里面不会自带对象的引用。 同样,非静态的方法想访问静态的方法与变量,可以通过类名去访问,也可以
通过对象去访问,(外部类通过对象去访问静态内部类中的方法与变量)
实例内部类可以看成一个非静态方法,非静态方法可以自由访问类中任何变量与方法,但是外部的非静态的方法和 静态方法想访问这个非静态方法,需要借助对象的引用。静态的方法里面可以有非静态的变量。(同样静态内部类中可以有非静态的方法与变量)
之前我们说的是非静态的方法可以直接访问任何类型的变量与方法,静态的方法只可以访问静态的方法与变量。不是静态的方法里面只能
有静态的方法与变量,也可以有非静态的字段(静态内部类中可以有非静态的方法与字段)。