目录
一、概述
二、反射与封装性
三、java.lang.Class的类的理解
1.获取Class的实例方式
2.Class不仅可以表示类,还可以表示其他它所学的类型。?
四、通过反射创建对应的运行时类的对象。
1.newInstance();调用此方法,创建对应的运行时类的对象。例:
2.反射的动态性
五、获取运行时类的完整结构
1.获取当前运行时类的属性结构
2.获取运行时类的方法结构
3.获取运行时类的构造器
4.获取运行时类的父类
5.获取运行时类的实现接口
6.获取运行时类所在的包
7.获取运行时类声明的注解
七.调用运行时类的指定结构
1.调用指定的结构
2.操作运行时类中指定的方法
3.指定的构造器
一、概述
Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期间借助于Reflection API获取到任何类的内部信息,并能直接操作任意对象的内部属性及方法。
二、反射与封装性
1.通过反射,可以调用类中私有构造器、私有方法、私有字段;也可以调用非私有的结构。在动态调用中使用反射。
2.反射与封装的矛盾
不矛盾,反射的初衷是为了调用类中公有的且是运行时类中的方法。
三、java.lang.Class的类的理解
加载到内存中国的类,称为运行时的类,此运行时的类就是class的一个实例。class的实例就对应一个运行时类。
1.获取Class的实例方式
①方式一:调用运行时类的名字.class
例:
Class clazz = Person.class;
②方式二:通过运行时类的对象,调用getClass()
Class clazz = P1.getClass;
③方式三:调用Class的静态方法:forName(String classPath)
Class clazz3 = Class.forName("com.ALi.java.Person");
④方式四:使用类的加载器ClassLoader(了解)
ClassLoader classloader = ReflectionTest.Class.getClassLoader();
classloader.loadClass("类的Path");
2.Class不仅可以表示类,还可以表示其他它所学的类型。?
数组中元素类型、维数一样它们的Class实例就相等。
四、通过反射创建对应的运行时类的对象。
1.newInstance();调用此方法,创建对应的运行时类的对象。 例:
Class clazz = Person.class;
Person obj = clazz.newInstance();
newInstance():
①内部调用运行时类的空参构造器。
②空参构造器的访问权限最小为缺省,通常设置为public。
在javaBean中要求提供一个public的空参构造器原因:
????????1.便于通过反射,创建运行时类的对象
????????2.便于子类继承此运行时类时,默认调用super()时,保证父类有此构造器。
2.反射的动态性
在代码运行时创建需要的对象。
五、获取运行时类的完整结构
1.获取当前运行时类的属性结构
Class clazz = Person.class();
Field[] f = clazz.getFields[];
①获取当前运行时类及其父类中声明为public访问权限的属性。
clazz.getDeclaredFields();
返回Field[]数组
②获取当前运行时类当中声明的所有属性(所有权限的属性都有),不含父类属性。
③获取属性权限 getModifiers()
Field[] fs = clazz.getDeclaredFields();
for(Field f :fs){
int modifier = f.getModifiers();
Modifier.toString(modifier);//将int数字转为对应的权限
}
④获取属性类型:getType()
class type = f.getType();
⑤获取变量名:getName()
String name = f.getName();
2.获取运行时类的方法结构
①获取父类中所有的public方法
getMethods();
返回值为Method[]
②获取当前运行时类的所有声明方法,不包含父类中声明的
getDeclaredMethods();
③获取方法的注解
getAnnotations();
for(Method m:declaredMethods){
Annotation[] annos = m.getAnnotations();
for(Annotation a:annos){
System.out.println(a);
}
}
④获取权限修饰符
getModifiers();
返回为int
Modifier.toString(int类型的权限修饰符);
⑤获取方法的返回值类型
m.getReturnType().getName();
⑥获取方法名
m.getName();
⑦获取形参列表
m.getParameterTypes();
⑧获取抛出的异常
m.getExceptionTypes();
3.获取运行时类的构造器
①获取当前运行时类中声明为public的构造器
clazz.getConstructors();
返回数组
②获取当前运行时类中声明的所有的构造器
clazz.getDeclaredConstructors();?
4.获取运行时类的父类
①clazz.getSuperclass();返回Class类型
②获取带泛型的父类
Type superclass = clazz.getGenericSuperclass();
③获取带泛型的父类的泛型
Type s = clazz.getGenericSuperclass();
ParameterizedType p = (ParameterizedType)s;
Type[] ac = p.getActualTypeArguments();
ac[0].getTypeName();
5.获取运行时类的实现接口
①
class clazz = Person.class;
Class[] interfaces = clazz.getInterface();
②获取父类实现的接口
Class[] interface = clazz.getSuperclass().getInterface();
6.获取运行时类所在的包
Package ap = clazz.getPackage();
7.获取运行时类声明的注解
Annotation a[] = clazz.getAnnotations();
七.调用运行时类的指定结构
1.调用指定的结构
①指定的属性:属性为publi。
Field id = clazz.getDield("属性名");//通常不用该方法。
方式二:
Person p = (Person)clazz.newInstance();
Field name = clazz.getDeclaredFiedld("属性名");
name.setAccessible(true);
name.set(p,新值);
name.get(p);
②设置当前属性的值
id.set(p,100);
参数p为对象;参数100为此属性设置为多少。
③获取当前属性的值
int PID = (int) id.get(p);
2.操作运行时类中指定的方法
①
Class clazz = Person.class();
Person p = (Person)clazz.newInstance();
//获取某个指定的方法
Method show = clazz.getDeclaredMethod("方法名",参数的类);
show.setAccessible(true);
②方法名.invoke(对象,形参);
参数1:调用方法的对象
参数2:实参
show.invoke(p,"CHN");返回show方法的返回值
在静态方法中p可以写为null
3.指定的构造器
Class clazz = Person.class;
Constructor cc = clazz.getDeclaredConstructor(String.class);//获取指定的构造器,参数为形参类型。
//保证此构造器可以访问
cc.setAccessible(true);
//调用此构造器运行时类的对象
person p = cc.newInstance("Tom");//Tom为有参构造器中的参数.
|