private
、 protected
、 static
,外部类不可以使用 这三个当内部类的方法调用变量时,
首先在该方法中查找该变量名的局部变量
在内部类中查找该变量名的成员变量
在内部类所在的外部类中查询该变量名的成员变量
如果没有查找到则编译错误
如果内部类方法中的局部变量、内部类成员变量、外部类成员变量的名字相同,则可通过使用 this、外部类类名.this作为限定来区分 。
外部类不能直接访问内部类的成员,需要创建内部类的实例
public class InnerClassTest {
public static void main(String[] args) {
Cow cow = new Cow(333);
cow.test();
}
}
class Cow {
private double weight;
private String var = "外部类成员变量";
public Cow() {
}
public Cow(double weight) {
this.weight = weight;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
private class CowLeg {
private String color;
private double length;
private String var = "内部类成员变量";
public CowLeg() {
}
public CowLeg(String color, double length) {
this.color = color;
this.length = length;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
private void info() {
String var = "局部变量";
System.out.println("CowLeg color:" + color + "--" + "length:" + length);
System.out.println("Cow weight:" + weight);
//同名变量引用
System.out.println("外部类成员变量:" + Cow.this.var);
System.out.println("内部类成员变量:" + this.var);//或CowLeg.this.var
System.out.println("局部变量:" + var);
}
}
public void test() {
//外部类引用内部类成员
new CowLeg("red", 20).info();
}
}
输出:
CowLeg color:red--length:20.0
Cow weight:333.0
外部类成员变量:外部类成员变量
内部类成员变量:内部类成员变量
局部变量:局部变量
public class StaticInnerClassTest {
public static void main(String[] args) {
new OuterClass.InnerClass().innerClassMethod();
new OuterClass().outerClassMethod();
}
}
class OuterClass {
private String var1 = "外部类成员变量";
private static String var2 = "外部类静态变量";
static class InnerClass {
// 静态内部类可以由静态变量和非静态变量
private String innerVar = "静态内部类成员变量";
private static String staticInnerVar = "静态内部类静态变量";
public void innerClassMethod() {
// System.out.println(var1); // 静态内部类无法调用外部类成员变量
System.out.println(var2); // 静态内部类调用外部类类变量
System.out.println(new OuterClass().var1); // 静态内部通过外部类的实例调用外部类成员变量
}
}
public void outerClassMethod() {
System.out.println(InnerClass.staticInnerVar);// 外部类调用内部类类变量
System.out.println(new InnerClass().innerVar);// 外部类调用内部类成员变量
}
}
输出:
外部类静态变量
外部类成员变量
静态内部类静态变量
静态内部类成员变量
局部内部类定义在方法中,且仅在该方法中有效。不能使用访问权限控制符和static修饰。
创建匿名内部类时会立即创建一个该类的实例,这个类定义立即消失,匿名内部类不能重复使用。匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,或实现一个接口。
//调用接口创建匿名内部类
public class AnonymousInnerClassTest {
public static void eatFruit(Fruit fruit) {
System.out.println("fruit color :" + fruit.getColor() + " -- fruit taste :" + fruit.getTaste());
}
public static void main(String[] args) {
eatFruit(new Fruit() {
@Override
public String getColor() {
return "red";
}
@Override
public String getTaste() {
return "sweet";
}
});
}
}
interface Fruit {
public String getColor();
public String getTaste();
}
//调用抽象类创建匿名内部类
class Anonymouslnner {
public void test(Device d) {
System.out.println("购买了一个 " + d.getName() + " ,花掉了 " + d.getPrice());
}
public static void main(String[] args) {
Anonymouslnner ai = new Anonymouslnner();
// 调用有参数的构造器创建 Device 匿名实现类的对象
ai.test(new Device(" 电子示波器") {
public double getPrice() {
return 67.8;
}
});
// 调用无参数的构造器创建 Device 匿名实现类的对象
Device d = new Device() {
// 初始化块
{
System.out.println(" 匿名内部类的初始化块 .. . ");
}
// 实现抽象方法
public double getPrice() {
return 56.2;
}
// 重写父类的实例方法
public String getName() {
return "键盘";
}
};
ai.test(d);
}
}
abstract class Device {
private String name;
public abstract double getPrice();
public Device() {
}
public Device(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
调用接口创建输出:
fruit color :red -- fruit taste :sweet
调用抽象类创建输出:
购买了一个 电子示波器 ,花掉了 67.8
匿名内部类的初始化块 .. .
购买了一个 键盘 ,花掉了 56.2
JDK8之前匿名内部类访问的局部变量必须使用final修饰,JDK8不在需要final修饰,但是会默认改变量式final修饰的,即在匿名内部类中访问的局部变量不能再被赋值。
interface A {
void test();
}
class ATest {
public static void main(String[] args) {
int age = 8; // ①
A a = new A() {
public void test() {
// 在 Java 8 以前下面语句将提示错误 : age 必须使用 final 修饰
// 从 Java 8 开始,匿名内部类、局部内部类允许访问非 final 的局部变量
System.out.println(age);
}
};
a.test();
//age = 1; // 不能重新赋值
}
}
原文:https://www.cnblogs.com/codebetter/p/11977811.html