java的反射机制
动态的访问某个类的方法,属性,创建对象。(只有在程序执行到某个特定的点的时候,才知道具体的方法,属性,对象是什么)。
1.1 java反射的API
1.1 java反射的API
1.2 Class类的作用
Class 类的实例表示正在运行的 Java 应用程序中的类和接口
Class类的实例表示的是内存中某个类或者接口对应的class文件。
File file=new File(“1.txt”);
package com.bjsxt.clz;
public class TestClass {
public static void main(String[] args) {
try {
//1获得Class的实例
//方式一:通过Calss提供的forName的静态方法,传入是一个类完全限定名
/***
* 首先查看内存是否存在指定完全限定名对应的类的class文件,如果有直接返回对应的Class的对象
* 如果没有,将该类加载进内存,返回Class的对象,如果指定的完全限定名不能加载对应的class文件
* 抛出异常
* ***/
Class clz=Class.forName("java.lang.String");
System.out.println(clz.getName());
//方式二:通过类名获得对应的Class实例
Class clz2=String.class;
//方式三:通过对象调用getClass获得
String str="abc";
Class clz3=str.getClass();
//Class的实例提供的方法
ClassLoader clzLoader1=clz.getClassLoader();
//获得Student类对应的class文件
Class clz4=Student.class;
ClassLoader clzLoader2=clz4.getClassLoader();
Class clz5=Pet.class;
ClassLoader clzLoader3=clz5.getClassLoader()
/**
* 所有classpath目录下的类都有AppClassLoader加载,而且所有自定类的加载是一样的。
* ***/
System.out.println(clzLoader1+"\t"+clzLoader2+"\t"+clzLoader3);
//创建此 Class 对象所表示的类的一个新实例:本次创建对象,调用的是某个类的无参数构造方法
Object s=clz4.newInstance();
Object p=clz5.newInstance();
System.out.println(s instanceof Student);
System.out.println(p instanceof Pet);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void method(Class clz){
//创建任意类的对象
//clz.newInstance();
}
}
1.3 Method类的作用
Method:封装的是类或接口上单独某个方法
package com.bjsxt.method;
import java.lang.reflect.Method;
public class TestMethod {
public static void main(String[] args) {
try {
//1 获得Class的对象
Class clz=Class.forName("com.bjsxt.method.Student");
//2获得Student中的所有公共方法包含父类中的
Method[] methods=clz.getMethods();
for(Method m:methods){
System.out.println(m);
}
//获得本类中声明的方法
Method[] meths=clz.getDeclaredMethods();
for(Method m:meths){
System.out.println("==="+m);
}
//获得某个指定方法名和参数类型的方法
Method method=clz.getDeclaredMethod("intro", String.class);
System.out.println("---"+method);
//3Method对象提供的方法
String methodName=method.getName();//方法名
int m=method.getModifiers();//权限
Class clz1=method.getReturnType();//返回值类型
System.out.println(methodName+"\t"+m+"\t"+clz1);
//Student s =new .....
Object student=clz.newInstance();
//完成method表示的某个方法的调用
method.invoke(student, "小强"); //student.intro("小强")
//obj.method(args);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
1.4 Constructor的作用
Constructor 完成Class实例 所表示的类的构造方法的封装
package com.bjsxt.cons;
import java.lang.reflect.Constructor;
import com.bjsxt.method.Student;
public class TestConstructor {
public static void main(String[] args) {
//1获得Class对象
Class clz=Student.class;
//2获得clz表示的类的构造方法
//获得所有构造方法
Constructor[] cons=clz.getConstructors();
for(Constructor c:cons){
System.out.println(c);
}
//获得某个特定的构造方法
try {
Constructor conDefault=clz.getConstructor();
System.out.println("=="+conDefault);
//通过默认的无参数构造方法,创建对象
Object obj=conDefault.newInstance();
System.out.println(obj instanceof Student);
//获得带参数的构造方法
Constructor conArgs=clz.getConstructor(String.class,Integer.class);
Object obj2=conArgs.newInstance("小强",120);
System.out.println(obj2);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
1.5 Field类的作用
Field 封装的是Class对象表示的类的所有属性
package com.bjsxt.field;
import java.lang.reflect.Field;
import com.bjsxt.method.Student;
public class TestField {
public static void main(String[] args) {
//1获得Class对象
Class clz=Student.class;
//获得clz表示的类中的所有属性
Field[] fls=clz.getDeclaredFields();
for(Field f:fls){
System.out.println(f);
}
try {
//获得指定名称的一个属性
Field f=clz.getDeclaredField("age");
System.out.println("----"+f);
//其他方法
System.out.println(f.getName());
System.out.println(f.getModifiers());
System.out.println(f.getType());
f.setAccessible(true);
//给特定属性赋值和取值
Object obj = clz.newInstance();
f.set(obj, 1000); //obj.xxx(1000);
//获得某个属性的值
Object x=f.get(obj);
System.out.println("==="+x);
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
1.5 练习
通过反射创建对象,访问对象的属性,方法
package com.bjsxt.demo;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.bjsxt.clz.Pet;
import com.bjsxt.method.Student;
public class TestDemo {
/***
* 通过反射创建对象,访问对象的属性,方法
* **/
public static void main(String[] args) {
//获得Class对象ss
//Class clz = Student.class;
Class clz = Pet.class;
Object obj=getInstance(clz);
System.out.println("------"+obj);
}
private static Object getInstance(Class clz) {
Object obj=null;
try {
//创建clz表示的类的对象
obj=clz.newInstance();
//获得所有属性
Field[] fls = clz.getDeclaredFields();
for(Field f:fls){
//获得每个字段的名称
String fname=f.getName();
//System.out.println(fname);
fname=fname.toLowerCase();
//获得某个属性对应set方法的方法名
String setMethod="set"+fname.substring(0, 1).toUpperCase()+fname.substring(1);
//获得某个属性对应get方法的方法名
String getMethod="get"+fname.substring(0, 1).toUpperCase()+fname.substring(1);
Class type=f.getType();//获得属性对应的类型
System.out.println("type="+type);
//获得属性对应的setMethod方法
Method set=clz.getDeclaredMethod(setMethod, type);
if(type.equals(String.class)){
set.invoke(obj, "乌龟");
}else if(type.equals(Integer.class)){
set.invoke(obj, 1000);
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return obj;
}
}