反射机制的详细代码理解

来源:互联网 发布:淘宝助理发布宝贝教程 编辑:程序博客网 时间:2024/06/08 15:39

1.类的加载器以及如何获取Class的实例

public class TestReflection {//关于类的加载器:ClassLoader@Testpublic void test5() throws Exception{ClassLoader loader1 = ClassLoader.getSystemClassLoader();//获取系统类加载器System.out.println(loader1);ClassLoader loader2 = loader1.getParent();//获取扩展类加载器System.out.println(loader2);ClassLoader loader3 = loader2.getParent();//引导类加载器无法被获取System.out.println(loader3);Class class1 = Person.class;ClassLoader loader4 = class1.getClassLoader();System.out.println(loader4);String className = "java.lang.Object";Class class2 = Class.forName(className);ClassLoader loader5 = class2.getClassLoader();//引导类加载器无法被获取System.out.println(loader5);ClassLoader loader = this.getClass().getClassLoader();InputStream is = loader.getResourceAsStream("com\\panda\\java\\jdbc.properties");Properties pros = new Properties();pros.load(is);String name = pros.getProperty("user");System.out.println(name);String password = pros.getProperty("password");System.out.println(password);}//如何获取Class的实例(3种)@Testpublic void test4() throws ClassNotFoundException{//1.调用运行时类本身的.class属性Class class1 = Person.class;System.out.println(class1.getName());Class class2 = String.class;System.out.println(class2.getName());//2.通过运行时类的对象获取Person person = new Person();Class class3 = person.getClass();System.out.println(class3.getName());//3.通过Class的静态方法获取String className = "com.panda.java.Person";Class class4 = Class.forName(className);System.out.println(class4.getName());//4.通过类的加载器ClassLoader classLoader = this.getClass().getClassLoader();Class class5 = classLoader.loadClass(className);System.out.println(class5.getName());}/* * java.lang.class:是反射的源头 * 我们创建了一个类,通过编译(javac.exe),生成对应的.class文件。之后我们使用java.exe加载(JVM的类加载器完成的) * 此.class文件,此.class文件加载到内存以后,就是一个运行时类,存在在缓存区。那么这个运行时类本身就是一个Class的实例! * 1.每一个运行时类只加载一次! * 2.有了Class的实例以后,我们才可以进行如下的操作: *     1)*创建对应的运行时类的对象 *     2)获取对应的运行时类的完整结构(属性、方法、构造器、内部类、父类、所在的包、异常、注解、...) *     3)*调用对应的运行时类的指定的结构(属性、方法、构造器) *     4)反射的应用:动态代理 */@Testpublic void test3(){Person person = new Person();Class class1 = person.getClass();//通过运行时类的对象,调用其getClass(),返回其运行时类System.out.println(class1);}//有了反射,可以通过反射创建一个类的对象,并调用其中的结构@Testpublic void test2() throws Exception{Class class1 = Person.class;//1.创建class1对应的运行时类Person类的对象Person person = (Person) class1.newInstance();//2.通过反射调用运行时类的指定的属性Field f1 = class1.getField("name");f1.set(person, "liuDeHua");System.out.println(person);Field f2 = class1.getDeclaredField("age");f2.setAccessible(true);f2.set(person, 20);System.out.println(person);//3.通过反射调用运行时类的指定的方法Method m1 = class1.getMethod("show");m1.invoke(person);Method m2 = class1.getMethod("display", String.class);m2.invoke(person, "CHN");}//在有反射以前,如何创建一个类的对象,并调用其中的方法、属性@Testpublic void test1(){Person person = new Person();person.setAge(10);person.setName("liming");System.out.println(person);person.show();//person.display("中国");}}
2.通过反射获取对应的运行时类的属性

public class TestField {//获取对应的运行时类的属性@Testpublic void test1(){Class class1 = Person.class;//1.getFields(),只能获取到运行时类中极其父类中声明为public的属性Field[] fields = class1.getFields();for (int i = 0; i < fields.length; i++) {System.out.println(fields[i]);}System.out.println();//2.getDeclaredFields(),获取运行时类本身声明的所有的属性Field[] fields2 = class1.getDeclaredFields();for(Field f : fields2){System.out.println(f.getName());}}/* * 权限修饰符 变量类型 变量名 * 获取属性的各个部分的内容 */@Testpublic void test2(){Class class1 = Person.class;Field[] fields2 = class1.getDeclaredFields();for(Field f : fields2){//1.获取每个属性的权限修饰符int i = f.getModifiers();String str = Modifier.toString(i);System.out.print(str + " ");//2.获取属性的变量类型Class type = f.getType();System.out.print(type.getName() + " ");//3.获取属性名System.out.print(f.getName());System.out.println();}}//调用运行时类指定的属性@Testpublic void test3() throws Exception, SecurityException{Class class1 = Person.class;//1.获取指定的属性//getField(String fieldName):获取运行时类中声明为public的指定属性名为fieldName的属性Field name = class1.getField("name");//2.创建运行时类的对象Person person = (Person) class1.newInstance();//3.将运行时类的指定的属性赋值name.set(person, "Jack");System.out.println(person);System.out.println();//getDeclaredField(String fieldName):获取运行时类中指定属性名为fieldName的属性Field age = class1.getDeclaredField("age");//由于属性权限修饰的限制,为了保证可以给属性赋值,需要在操作前使得此属性可被操作age.setAccessible(true);age.set(person, 22);System.out.println(person);}}

3.通过反射获取运行时类的方法

public class TestMethod {//1.获取运行时类的方法@Testpublic void test1(){Class class1 = Person.class;//1.getMethods(),获取运行时类及其父类中所有的声明为public的方法Method[] methods = class1.getMethods();for(Method m : methods){System.out.println(m);}System.out.println();//2.getDeclaredMethods(),获取运行时类本身声明的所有的方法Method[] methods2 = class1.getDeclaredMethods();for(Method m : methods2){System.out.println(m);}}//注解 权限修饰符 返回值类型 方法名 形参列表 异常@Testpublic void test2(){Class class1 = Person.class;Method[] methods2 = class1.getDeclaredMethods();for(Method m : methods2){//1.注解Annotation[] ann = m.getAnnotations();for(Annotation a : ann){System.out.println(a);}//2.权限修饰符String str = Modifier.toString(m.getModifiers());System.out.print(str + " ");//3.返回值类型Class returnType = m.getReturnType();System.out.print(returnType.getName() + " ");//4.方法名System.out.print(m.getName() + " ");//5.形参列表System.out.print("(");Class[] params = m.getParameterTypes();for(Class p : params){System.out.print(p.getName() + " ");}System.out.print(")");//6.异常类型Class[] exps = m.getExceptionTypes();for (int i = 0; i < exps.length; i++) {System.out.println(exps[i].getName());}System.out.println();}}//调用运行时类中的指定的方法@Testpublic void test3() throws Exception{Class class1 = Person.class;//getMethod(String methodName,Class ... params):获取运行时类中声明为public的指定的方法Method m1 = class1.getMethod("show");Person person = (Person) class1.newInstance();//调用指定的方法:Object invoke(Object obj,Object ... obj)Object returnVal = m1.invoke(person);//我是一个人System.out.println(returnVal);//nullMethod m2 = class1.getMethod("toString");Object returnVal1 = m2.invoke(person);System.out.println(returnVal1);//Person [name=null,age=0]//对于运行时类中静态方法的调用Method m3 = class1.getMethod("info");m3.invoke(Person.class);//中国人//getDeclaredMethod(String methodName,Class ... params):获取运行时类中声明了的指定的方法Method m4 = class1.getDeclaredMethod("display",String.class);m4.setAccessible(true);Object value = m4.invoke(person,"CHN");//我的国籍是:CHN}}
4.通过反射调用指定的构造器

public class TestConstructor {@Testpublic void test1() throws Exception{String className = "com.panda.java.Person";Class class1 = Class.forName(className);//创建对应的运行时类的对象.使用newInstan(),实际上就是调用了运行时类的空参的构造器//要想能创建成功:1.要求对应的运行时类要有空参的构造器。2.构造器的权限修饰符的权限要足够Object object = class1.newInstance();Person person = (Person) object;System.out.println(person);}@Testpublic void test2() throws ClassNotFoundException{String className = "com.panda.java.Person";Class class1 = Class.forName(className);Constructor[] cons = class1.getDeclaredConstructors();for(Constructor constructor : cons){System.out.println(constructor);}}//调用指定的构造器,创建运行时类的对象@Testpublic void test3() throws Exception{String className = "com.panda.java.Person";Class class1 = Class.forName(className);Constructor constructor = class1.getDeclaredConstructor(String.class,int.class);constructor.setAccessible(true);Person person = (Person) constructor.newInstance("李明",21);System.out.println(person);}} 
5.通过反射获取其他
public class TestOthers {//1.获取运行时类的父类@Testpublic void test1(){Class class1 = Person.class;Class supercClass = class1.getSuperclass();System.out.println(supercClass);}//2.获取带泛型的父类@Testpublic void test2(){Class class1 = Person.class;Type type = class1.getGenericSuperclass();System.out.println(type);}//3.获取父类的泛型@Testpublic void test3(){Class class1 = Person.class;Type type = class1.getGenericSuperclass();ParameterizedType pType = (ParameterizedType) type;Type[] ars = pType.getActualTypeArguments();System.out.println(((Class)ars[0]).getName());}//4.获取实现的接口@Testpublic void test4(){Class class1 = Person.class;Class[] interfaces = class1.getInterfaces();for(Class c : interfaces){System.out.println(c);}}//5.获取所在的包@Testpublic void test5(){Class class1 = Person.class;Package package1 = class1.getPackage();System.out.println(package1);}//6.获取注解@Testpublic void test6(){Class class1 = Person.class;Annotation[] anns = class1.getAnnotations();for(Annotation annotation : anns){System.out.println(annotation);}}}
附录:

1.父类Creature

public class Creature<T> {public double weight;public void breath(){System.out.println("呼吸!");}}

2.Person类

@MyAnnotation(value = "panda")public class Person extends Creature<String> implements Comparable,MyInterface{public String name;private int age;int id;public Person() {super();}public Person(String name) {super();this.name = name;}public Person(String name, int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public int getId() {return id;}public void setId(int id) {this.id = id;}@MyAnnotation(value = "abc123")public void show(){System.out.println("我是一个人");}private void display(String nation)throws Exception{System.out.println("我的国籍是:" + nation);}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + "]";}@Overridepublic int compareTo(Object o) {// TODO Auto-generated method stubreturn 0;}public static void info(){System.out.println("中国人!");}class Bird{}}
3.注解类

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})@Retention(RetentionPolicy.RUNTIME)public @interface MyAnnotation {String value();}
4.接口类
public interface MyInterface extends Serializable{}
5.jdbc.properties文件
user=rootpassword=123456









0 0