内部类,java类库经常使用的一种形式,这次有时间,记载一下,以下全是代码,描述全在注释当中,可以直接复制代码,进行测试
----------------------------------我是分割线------------------------------------
public class InnerClass {
private String msg = "外部类private修饰的字符串";
public String msg1 = "外部类public修饰的字符串";
static int number = 0;
final double d = 1.2d;
static final float F = 1.3f;
/**
普通的内部类;
限制跟使用如下:
1:内部类可以使用外部类的全局变量
2:内部类内,不能定义静态方法跟静态变量,因为内部类是依赖外部类存在的
只有实例化外部类了,JVM才会去加载内部类,
而静态方法跟静态变量都是依赖类存在的,
3:当内部类修改了外部类的全局变量,外部类的全局变量也会被修改
4:内部类中,不允许在定义静态内部类,但是可以接着定义非静态内部类
5:内部类也可以继承,实现接口
*/
public class RuleInnerClass{
/*
但是可以定义普通的内部类
*/
class InnerInnerClass{
}
/*
内部内中,不允许定义静态内部类
*/
//static class StaticInnerClass{
//
//}
/*
* 编译器会报错,普通内部类不允许定义静态变量
*/
//static int a = 0;
/*
也不允许定义静态方法
*/
//public static void printmsg(){
//
//}
public void print(){
System.out.println(msg);
System.out.println(msg1);
System.out.println(number);
System.out.println(d);
System.out.println(F);
}
/**
构建私有内部类实例,调用其方法
*/
public void printPrivateInnerClass(){
PrivateInnerClass privateInnerClass = new PrivateInnerClass();
privateInnerClass.print();
}
}
/**
私有内部类的功能限制跟普通内部类一样
不过私有的内部类,不能在外部类以外进行实例化
*/
private class PrivateInnerClass{
public void print(){
System.out.println(msg);
System.out.println(msg1);
System.out.println(number);
System.out.println(d);
System.out.println(F);
}
}
/**
静态内部类;
限制跟使用如下:
1:静态内部类只能使用外部类的静态变量
2:静态内部类内,可以定义非静态变量跟静态变量以及静态方法,因为静态内部类不依赖于外部类的实例
3:静态内部类也可以实现接口,跟继承类
4:静态内部类内部,还可以定义静态内部类跟非静态内部类
*/
static class StaticInnerClass implements Contents{
int a = 0;
static int i = 1;
class IsNotStaticInnerInnerClass{
}
static class StaticInnerInnerClass{
}
public static void printStatic(){
System.out.println("静态内部类的静态方法");
}
public void print(){
/*
静态内部类里面,不允许调用外部类的非静态变量
*/
//System.out.println(msg);
System.out.println(number);
System.out.println(F);
System.out.println(a);
System.out.println(i);
}
}
/**
* 局部内部类限制跟普通内部类差不多
* 1:都是不能定义静态属性跟方法也不能定义静态内部类
* 2:局部内部类可以调用外部类的所有全局变量
* 3:局部内部类的内部类可以定义普通局部内部类
* 4:局部内部类调用局部变量,必须是final修饰的,因为局部变量在方法调用结束就会销毁,但是局部内部类不会销毁
* 5:局部内部类可以继承跟实现接口
* 6:局部内部类不能当做返回参数返回,如果要返回局部内部类,实现一个接口或者继承一个类,通过向上转型返回
* 7:方法外局部内部类引用,只能通过继承类或者实现接口向上转型返回,因为局部内部类的作用域只能限于方法内,所以不能再方法外进行实例化
*/
public Contents getLocalInnerClass(){
final String methodFiled = "局部变量";
/*
不能定义一个局部静态类
*/
//static class LocalInnerStaticClass{
//
//}
/*
局部内部类,不能使用修饰符
*/
class LocalInnerClass implements Contents{
int localMenthodFiled = 0;
/*
不能定义静态变量
*/
//static int a = 0;
public void print(){
System.out.println(localMenthodFiled);
System.out.println(number);
System.out.println(msg);
System.out.println(methodFiled);
}
/*
局部内部类也不能定义静态方法
*/
//public static void staticPrint(){
//
//}
/*
也不能定义静态内部类
*/
//static class LocalStaticClass{
//
//}
}
return new LocalInnerClass();
}
/**
* 匿名内部类限制跟局部内部类差不多
* 1:都是不能定义静态属性跟方法也不能定义静态内部类
* 2:匿名内部类可以调用外部类的所有全局变量
* 3:匿名内部类的内部类可以定义普通局部内部类
* 4:匿名内部类调用局部变量,必须是final修饰的,因为局部变量在方法调用结束就会销毁,但是匿名内部类不会销毁
* 5:匿名必须实现一个接口,或者集成一个类
* 6:匿名内部类不能当做返回参数返回(因为它压根就没名字),但是可以返回匿名内部类实现的接口或者继承类,从而返回匿名内部类的引用
*/
public Contents getContents(){
final int w = 1;
return new Contents() {
int q = 0;
/*
不能定义静态变量
*/
//static int s = 2;
@Override
public void print() {
/*
可以调用外部类的所有变量
*/
System.out.println(msg);
System.out.println(msg1);
System.out.println(number);
System.out.println(d);
System.out.println(F);
/*
调用局部变量,必须是final修饰
*/
System.out.println(w);
System.out.println(q);
System.out.println("我是匿名内部类");
}
/*
不能定义静态方法
*/
//public static void staticPrint(){
//
//}
/*
不能定义静态内部类
*/
//static class StaticClass{
//
//}
/*
可以定义非静态内部类
*/
class IsNotStaticClass{
}
};
}
}
public class InnerTest {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
InnerClass innerClass = new InnerClass();
/*
常规内部类构建方法有两种
1: 是通过外部类.new 内部类类名来创建
2: 是通过反射创建
*/
/**
* 普通创建内部类的方法
*/
InnerClass.RuleInnerClass ruleInnerClass = innerClass.new RuleInnerClass();
ruleInnerClass.print();
System.out.println("--------------------------------------");
ruleInnerClass.printPrivateInnerClass();
/**
* 反射创建内部类的方法
* 需要注意的是,通过反射创建内部类,地址是报名.外部类类名$内部类类名
* 而且构建内部类,需要传入一个外部类的引用,
* 所以必须通过Constructor类的newInstance方法构建内部类
*/
Class c =Class.forName("com.demo.innerClass.InnerClass$RuleInnerClass");
System.out.println("我需要一个外部对象:"+ Arrays.toString(c.getDeclaredConstructors()));
Constructor constructor = c.getConstructor(InnerClass.class);
InnerClass.RuleInnerClass o = (InnerClass.RuleInnerClass)constructor.newInstance(new InnerClass());
o.print();
System.out.println("--------------------------------------");
/*
创建静态内部类,不需要外部类的实例,可以通过 new 外部类.静态内部类进行创建
调用静态内部类的静态方法,是通过 外部类.静态内部类.静态方法就可以调用
调用静态内部类的静态变量,同理,只不过是把静态方法,变为静态变量
*/
InnerClass.StaticInnerClass staticInnerClass = new InnerClass.StaticInnerClass();
staticInnerClass.print();
InnerClass.StaticInnerClass.printStatic();
System.out.println("--------------------------------------");
/*
方法外创建局部内部类,只能通过继承类或者实现接口向上转型返回
因为局部内部类的作用域只能限于方法内
*/
Contents contents = innerClass.getLocalInnerClass();
contents.print();
System.out.println("--------------------------------------");
/*
匿名内部类,只能通过向上转型返回它的实例引用
*/
Contents contents1 = innerClass.getContents();
contents1.print();
}
}
到这,文章就结束了!
以上,均为本人测试而得出的结果,可能会有出入,或者错误,欢迎指正
欢迎转载,请注明出处跟作者,谢谢!