反射·类加载与垃圾回收
常用单词:
反 射 reflect;
属 性 Field;
构 造 Constructor;
方 法 Method;
被声明的 Declared
调 用 invoke
动态性:运行期探究和使用编译期未知的东西---反射带给Java的动态性。包括:类,构造,属性和方法等。
要求:
1.学会通过反射产生对象;
2.通过反射探究类,方法,属性等;
3.体会在运行期探究使用类的任意构造,任意方法,任意属性,体会其动态性;
类加载:
由类加载器完成,类的class文件读入内存后,就会创建一个Java.lang.Class对象。
一旦某个类被加载入JVM中,同一个类就不会被在次载入。加载一个类,
就是把这个类放入class对象中。
连接:
把类的二进制数据合并到jre中。
初始化:
JVM负责对类初始化也就是对静态属性进行初始化。
自审:
Java的反射技术是Java程序的特征之一,它允许运行中的Java程序自身检查,
并能直接操作程序的内部属性。
反射:
1.获取class对象;
2.通过class对象探究一个类的信息;
3.操作从class对象中探究出的信息;使用reflectiongAPI探究;
1 .反射获取对象:
根据实例对象获取Class对象
实现方法:调用实例对象的getClass();该方法来自Object类;
适用范围:引用数据类型;
动态性:无;
student stu = new Student();
Class stuClass = stu.getClass();
Class strClaa = "hello".getClass();
int[] intArray = new int[6];
Class arrayClass = intArray.getClass();
2.根据类型名获取Class对象
实现方法:条用类型名.class;
适用范围:所有的类型(基本,引用,甚至包括void);
动态性:无;
Class stuClass1 = student.class;
Class strClass1 = string.class;
Class arrayClass1 = int[].class;
Class integerClass = Integer.class;获取包装类Integer的class对象;
Class intclass1 = Integer.TYPE; 获取int的class对象, JDK1.5以前
Class intClass = int.class; JDK1.5以后
Class voidClass = void.class;
System.out.println(stuClass0 = stuClass1);不管适用哪种方式获取,一个类型只有一个class对象
3.根据类型的字符串名称获取Class对象;
实现方法:调用class.foeName("类的限定名");
适用范围:只有类类型(包括接口);
动态性:有;
Class stuClass2 = null;
stuClass2 = Class.forName("com.lovo.bean.Student");
获取class对象中的信息
1.探究一个类声明部分信息:
String packageName = stuClass2.getPackage().getName();得到包名
Systen.out.print("package"+packageName +";");
String packageName = stuClass2.getName();得到全类名
class Name = stuClass2.getSimpleName();得到简单类名
Systen,out.print("className");
int ClassMod = stuClass2.getModifiers();得到修饰符,返回的数字
String classModStr = Modfier.toString(classMod);利用工具方法,将整型修饰符转换成字串符;
class superStuClass = stuClass.getSuperclass();得到父类的class对象
string superClassName = superStuClass.getName();得到父类的类名;
class[] interClasses = stuClass2.getinterfaces();得到本类实现接口的class对象(可以是多个,所以是数组)
string allInter = "";
for(int i = 0;i < interClasses.length;i++){
allInter += interClasses[i].getName();
if(i < interClasses.length - 1){
allInter += ",";
}
}
2.探究属性
Field[] allpublicFields = stuClass2.getFields();得到所有的公共属性(public)
Field[] allFields = stuClass2.geDeclaredtFields();得到所有申明的属性
Field thepublicField = StuClass2.getField(socore);只能得到指定的公共属性(报异常用try catch语句块)
Field theField = StuClass2.geDeclaredtField("socore");得到某个被声明的属性,不受访问修饰符限制
打印属性:
String field = field.getName();得到属性名
Class fieldType = field.getType();得到属性名;
String fieldTypeName = fieldType.getName();得到类型名
int fieldMod = field.getModifiers();得到属性对应的修饰符(返回数字);
String fildModStr = Modfier.toString(fielsMod);(返回字符串)
3.探究构造
Constructor [] allpublicCons = stuClass2.getConstructors();得到所有公共构造
Constructor [] allCons = stuClass2.getDeclaredConstructors();得到所有被声明构造
Constructor thePubliccon = stuClass2.getConstructor(string.classs,int.class,boolean.class);得到某个指定的公共构造方法
Constructor thecon = stuClass2.getDeclaredConstructor();得到某个被声明的公共构造方法
打印构造:
for(Constructor con:allcons){
String conName = con.getNmae();得到构造方法名字(全部类名)
Class []paramClasses = con.getParmeterTypes();得到构造方法参数列表
System.out.print(conNmae + "("+ params +")");
Stringparams = "";
if(paramClasses != null && paramClasses.length > 0){
for(int i = 0;i <paramClasses.length;i ++){
param += paramClasses[i].getName()'
if(i <paramClasses.length -1){
param += ",";
}
}
}
int conMod = con.Modifiers()
String conModStr = Modfier.toString(consMod);
}打不出方法具体实现。代码放在代码段。
当数组作为形参的时候,...的声明方式是一种语法糖;
外部调用者,无需一定创建数组实参;
内部实现者,仍然按数组的方式使用形参;
public void tt(int ...array){
}
public void test(){
tt();
tt(1);
tt(1,2);
tt(1,2,3,4,5,6,7);
}
4.探究方法
Method [] allPublicMethod = null;
Method [] allMethod = null;
根据反射探究到的信息进行操作
1.根据Constructor对象,产生实例对象
实现一:调用Constructor对象的NewInstance方法即可;
try {
//得到指定的某个公共构造方法
Constructor thePublicCon = stuClass2.getConstructor(String.class,int.class,boolean.class);
student student = (student) thePublic.newInstance("zhang3"18,true);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
实现二:直接调用Class对象的newInstance方法---前提是只能调用到公共无参的构造
Student Stu0 = (Student)StuClass2.newInstence();
2.根据Field对象,对属性进行取值和赋值
实现:调用Field的get/set方法
赋值:注意第一个参数,代表给哪一个student对象的这个属性赋值;
取值:注意第一个参数,代表从哪一个student对象的这个属性取值;
3.根据method对象,对方法进行调用
实现:调用Method对象的invoke方法
Method thePublicMethod = stuClass2.getMethod();得到指定公共方法
thePublicMethod.invoke(stu,"是否传参");
掌握:
3种方式;
ClassforName
Feild
construct
method
Declared