您的位置:首页 > 其它

反射、类加载与垃圾回收

2016-05-03 20:46 411 查看

反射、类加载与垃圾回收

Java是一种有一定动态性的语言。

动态性:它可以在运行期探究和使用编译期未知的东西,包括类、构造、属性、方法等。

目标:使用反射产生对象,通过反射探究类(属性、构造、方法),在运行期去探究和使用任意属性、构造及方法。

类加载

类的加载机制

类加载:就是把一个类的信息放入一个Class对象当中去。

连接:把类的二进制的数据合并到JRE中。

初始化:

反射

概念:在运行时探究和使用未知的类。

反射步骤:

1.获取Class信息。

//1-1、根据实例对象获取Class对象。
//实现方法:调用实例对象获取对象的getClass().该方法来自Object类。
//适用范围:引用数据类型,
//动态性:无
Student stu = new Student();
Class stuClass = stu.getClass();
Class strClass = "hello".getClass();
int[] intArray = new int[6];
Class arrayClass = intArray.getClass();

//1-2、根据类型名获取Class对象
//实现方法:调用类型名。class。
//适用范围:所有的类型(基本、引用、甚至包括void)
//动态性:无
Class stuClass0 = Student.class;
Class strClss1 = String.class;  //该方式在JDK1.5以后才有
Class arrayClass0 = int[].class;
Class voidClass = void.class;
Class intClass = Integer.class;
Class intClass1 = Integer.TYPE;//该方式在JDK1.5以前

//1-3、根据类型的字符串名称获取Class对象。
//实现方式:调用Class。forName("类的限定名")
//适用范围:只有类类型(包括接口)
//动态性:有
Class stuClass1 = null;
try {
String className = new Scanner(System.in).next();
stuClass1 = Class.forName(className);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


2.通过Class对象探究一个类的信息。

//2-1、探究一个类的申明部分信息
String packageName = stuClass2.getPackage().getName();//得到包名
System.out.println("package " + packageName + ";");
String className = stuClass2.getName();//得到全类名
className = stuClass2.getSimpleName();//得到简单类名
int classMod = stuClass2.getModifiers();//得到修饰符,返回的数字
String classModStr = Modifier.toString(classMod);//利用工具方法,将整型修饰符转换成字符串
Class superStuClass = stuClass2.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 += ",";
}
}
//打印类的申明部分
System.out.println(classModStr + " class " + className +
" extends " + superClassName +
" implements " + allInter + "{");

//2-2、探究属性
System.out.println("//属性");
Field[] allPublicFields = stuClass2.getFields();//得到所有的公共属性
Field[] allFields = stuClass2.getDeclaredFields();//得到所有被申明的属性
try {
Field thePublicField = stuClass2.getField("score");//得到指定的某个公共属性
Field theField = stuClass2.getDeclaredField("name");//得到指定的某个被申明的属性
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//打印属性
for(Field field : allFields){
String fieldName = field.getName();//得到属性名
Class fieldType = field.getType();//得到属性类型
String fieldTypeName = fieldType.getName();
int fieldMod = field.getModifiers();//得到属性对应的修饰符
String fieldModStr = Modifier.toString(fieldMod);
System.out.println("\t" + fieldModStr + " " + fieldTypeName + " " + fieldName);
}

//2-3、探究构造
System.out.println("//构造方法");
Constructor[] allPublicCons = stuClass2.getConstructors();//得到所有的公共构造
Constructor[] allCons = stuClass2.getDeclaredConstructors();//得到所有被申明的构造

try {
//得到指定的某个公共构造方法
Constructor thePublicCon = stuClass2.getConstructor(String.class,int.class,boolean.class);
//得到指定的某个被申明的构造方法
Constructor theCon = stuClass2.getDeclaredConstructor();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

//打印构造
for(Constructor con : allCons){
String conName = con.getName();//得到构造方法的名字
Class[] paramClasses = con.getParameterTypes();//得到构造方法的参数列表
String params = "";
if(paramClasses != null && paramClasses.length > 0){
for(int i = 0; i < paramClasses.length; i++){
params += paramClasses[i].getName();
if(i < paramClasses.length - 1){
params += ",";
}
}
}
int conMod = con.getModifiers();//得到构造方法的修饰符
String conModStr = Modifier.toString(conMod);

System.out.println("\t" + conModStr + " " + conName + "(" + params + ")");
}

//2-4、探究方法
System.out.println("//普通方法");
Method[] allPublicMethods = stuClass2.getMethods();//得到所有的公共方法
Method[] allMethods = stuClass2.getDeclaredMethods();//得到所有被申明的方法

try {
Method thePublicMethod = stuClass2.getMethod("test1");//得到指定的某个公共属性
Method theMethod = stuClass2.getDeclaredMethod("test3",int.class,String.class);//得到指定的某个被申明的属性
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

//打印方法

for(Method method : allMethods){
String methodName = method.getName();//得到方法的名字
Class[] paramClasses = method.getParameterTypes();//得到方法的参数列表
Class[] methodExs = method.getExceptionTypes();//得到方法的返回类型
String params = "";
String exs = "";
if(paramClasses != null && paramClasses.length > 0){
for(int i = 0; i < paramClasses.length; i++){
params += paramClasses[i].getName();
if(i < paramClasses.length - 1){
params += ",";
}
}
}
if(methodExs != null && methodExs.length>0){
exs="throws";
for(int j=0; j<methodExs.length;j++){
exs +=methodExs[j].getName();
if(j<exs.length()-1){
exs += ",";
}
}
}
int methodMod = method.getModifiers();//得到构造方法的修饰符
String methodModStr = Modifier.toString(methodMod);
Class methodRe = method.getReturnType();
System.out.println("\t" + methodModStr + " " + methodRe + " " + methodName+" "+params+" "+exs+"{");
}


3.操作从Class中探究出的信息。

//3-1、根据Constructor对象,产生实例对象
//实现一:调用Constructor的newInstance方法。
try {
//得到指定的某个公共构造方法
Constructor thePublicCon = stuClass2.getConstructor(String.class,int.class,boolean.class);
try {
Student student = (Student)thePublicCon.newInstance("zhang3",18,true);
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//实现二:直接调用Class对象的newInstance方法--前提是只能调用到公共无参构造
try {
Student stu0 = (Student)stuClass2.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

//3-2、根据Field对象,对属性进行取值和赋值。
try {
Field thePublicField = stuClass2.getField("score");
thePublicField.set(stu, 100);//赋值(注意第一个参数,代表的是给哪个对象的这个属性赋值)
thePublicField.get(stu);//取值(参数代表从哪个对象得到了这个值)
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

//3-3、根据method对象,对方法进行调用
//实现:调用Method对象的invoke方法
try {
Method thePublicMethod = stuClass2.getMethod("test3",int.class);
thePublicMethod.invoke(stu,4);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: