一、反射需要用的API
1.获取字节码对象
Class.forName("类的全路径");注意:传入的是类的全路径名,包含包名.类名,而且会抛出异常
类名.class 注意:这个写法需要自己手动接一下获取的字节码对象,不能用快捷方式的
对象.getCalss();注意:经常与匿名对象一起使用
2.常用方法
1)获取包名 类名
clazz.getPackage().getName()//包名
clazz.getSimpleName()//类名
clazz.getName()//完整类名
2)获取成员变量定义信息
getFields()//获取所有公开的成员变量,包括继承变量
getDeclaredFields()//获取本类定义的成员变量,包括私有,但不包括继承的变量
getField(变量名)
getDeclaredField(变量名)
3)获取构造方法定义信息
getConstructor(参数类型列表)//获取公开的构造方法
getConstructors()//获取所有的公开的构造方法
getDeclaredConstructors()//获取所有的构造方法,包括私有
getDeclaredConstructor(int.class,String.class)
4)获取方法定义信息
getMethods()//获取所有可见的方法,包括继承的方法
getMethod(方法名,参数类型列表)
getDeclaredMethods()//获取本类定义的方法,包括私有,不包括继承的方法
getDeclaredMethod(方法名,int.class,String.class)
5)反射新建实例
clazz.newInstance();//执行无参构造创建对象
clazz.getConstructor(int.class,String.class)//要先获取构造方法
clazz.newInstance(666,"海绵宝宝");//再执行含参构造创建对象
6)反射调用成员变量
clazz.getDeclaredField(变量名);//获取变量
field.setAccessible(true);//使私有成员允许访问
field.set(实例,值);//为指定实例的变量赋值,静态变量,第一参数给null
field.get(实例);//访问指定实例变量的值,静态变量,第一参数给null
7)反射调用成员方法
Method m = Clazz.getDeclaredMethod(方法名,参数类型列表);
m.setAccessible(true);//使私有方法允许被调用
m.invoke(实例,参数数据)//让指定实例来执行该方法
3.关于反射的学习方式
如果能够直接操作源代码,就不需要使用反射
反射经常用于源码与三大框架底层之中,熟练掌握有助于编程思想的提高
4.单元测试方法
它是Java运行程序的最小单位
格式:@Test+public+void+没有参数
二、内部类
1.我们可以把内部类看作是外部类的一个特殊的成员
2.内部类可以直接使用外部类的所有资源,包括私有资源
3.外部类想要使用内部类的资源,需要创建内部类的对象才能使用
1.成员内部类
1)位置:类里方法外
2)被private修饰
被私有化的内部类在main()中无法直接创建其对象
可以在私有内部类所处的外部类当中,创建一个公共的方法供外界调用,这个方法就可以用来创建私有内部类的对象并且调用私有内部类的功能
3)被static修饰
static静态,优先于对象加载,静态可以通过类名直接调用,静态只能调用静态
静态内部类可以不创建外部类对象,直接通过外部类类名.的方式创建内部类对象
如果静态内部类中还有静态方法,那么我们可以不创建一个对象,直接通过链式加载的方式使用这个静态方法
2.局部内部类
1)位置:方法里
直接通过外部类创建对象,调用局部内部类所处的这个方法时,并不会触发局部内部类的功能!
所以如果想要使用局部内部类的功能,需要在局部内部类所处的方法中创建局部内部类的对象并且调用这个局部内部类的功能!
3.匿名内部类
没有名字的对象,只能使用一次,一次只能调用一个方法,如果想要调用多次,或者是多个方法,就需要创建普通对象,或者是多个匿名对象才能完成
匿名内部类通常与匿名对象结合在一起使用
new Inter1(){我是一个匿名内部类,我来实现方法}.eat();