1 package com.gh.ref; 2 3 public class Person { 4 private String name; 5 private int age; 6 private char sex; 7 private void say(){ 8 System.out.println("我是"+name); 9 } 10 public String getName() { 11 return name; 12 } 13 public void setName(String name) { 14 this.name = name; 15 } 16 public int getAge() { 17 return age; 18 } 19 public void setAge(int age) { 20 this.age = age; 21 } 22 public char getSex() { 23 return sex; 24 } 25 public void setSex(char sex) { 26 this.sex = sex; 27 } 28 public String toString() { 29 return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]"; 30 } 31 public Person(String name, int age, char sex) { 32 super(); 33 this.name = name; 34 this.age = age; 35 this.sex = sex; 36 System.out.println("调用Person有参构造方法"); 37 } 38 public Person() { 39 super(); 40 System.out.println("调用Person无参构造方法"); 41 } 42 43 }
1 package com.gh.ref; 2 import java.lang.reflect.Constructor; 3 import java.lang.reflect.Field; 4 import java.lang.reflect.InvocationTargetException; 5 import java.lang.reflect.Method; 6 import java.lang.reflect.Modifier; 7 /** 8 * 反射 9 * @author ganhang 10 */ 11 public class RefDemo { 12 public static void main(String[] args) throws Exception { 13 Person p=new Person("小白",18,‘男‘); 14 Person p1=new Person("小黑",10,‘女‘); 15 //创建Class对象方法一 16 Class personClass=p.getClass(); 17 Class personClass1=p1.getClass(); 18 System.out.println(personClass==personClass1); 19 /** 20 * true是因为java虚拟机先把Person.class通过类加载器加载到内存,加载到内存就是以Class类型存在的 21 * 但是两个对象只加载一次Person,所以他们的内存地址是 一样的;这和instanceof的功能本质一样 22 */ 23 //创建Class对象方法二 24 Class personClass3=Person.class;//一个Class对象代表一份字节码,相同类型的对象的字节码是一样的 25 System.out.println(personClass3==personClass1); 26 //int.class; 27 //void.class; 28 //创建Class对象方法三 29 Class personClass4=Class.forName("com.gh.ref.Person");//可能类找不到会抛异常,注意加包名 30 System.out.println(personClass4==personClass1); 31 //--------通过类信息实例化对象-------- 32 //调用无参构造方法 33 Person p3; 34 try { 35 p3 = (Person)personClass4.newInstance(); 36 System.out.println(p3);//因为调用无参构造所以全为空,如果类中没有无参构造方法将会报异常 37 } catch (InstantiationException | IllegalAccessException e1) { 38 e1.printStackTrace(); 39 } 40 //调用有参构造方法 41 Constructor[] cons= personClass4.getConstructors();//获得当前类的所以构造方法 42 Person p4=null; 43 try { 44 //传指定参数的Class对象 45 Constructor c=personClass4.getConstructor(String.class,int.class,char.class); 46 p4=(Person) c.newInstance("小花",18,‘女‘); 47 System.out.println(p4); 48 } catch (Exception e) { 49 e.printStackTrace(); 50 } 51 //----------通过类取得类信息------- 52 System.out.println("包信息:"+personClass.getPackage().toString());//返回一个包类 53 System.out.println("类名:"+personClass.getName()); 54 //获取类的方法信息 55 Method[] ms=personClass.getMethods(); 56 /** 57 * 返回一个包含某些 Method 对象的数组, 58 * 这些对象反映此 Class 对象所表示的类或接口 59 *(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法 60 * 如果只要本类自己定义方法(包括私有)可以用getDeclaredMethods() 61 */ 62 for (Method m : ms) { 63 //获取访问修饰符返回的是数字,需要Modifier来转 64 System.out.println("方法名"+Modifier.toString(m.getModifiers())+"-"+m.getName()); 65 } 66 //获取类的属性信息,getDeclaredFields()获取私有 67 Field[] fs=personClass.getFields();//公有属性,Person没有 68 for (Field f : fs) { 69 System.out.println("属性名:"+f.getName()); 70 } 71 System.out.println("---------调用方法--------"); 72 try { 73 Method m=personClass4.getMethod("setName", String.class); 74 m.invoke(p4, "花花"); 75 System.out.println(p4); 76 //如果调用私有方法say 77 Method m1=personClass4.getDeclaredMethod("say");//注意可以调私有方法的方法 78 m1.setAccessible(true);//忽略验证修饰符,让其对外可见 79 m1.invoke(p4); 80 } catch (Exception e) { 81 e.printStackTrace(); 82 } 83 System.out.println("---------调用属性--------"); 84 Field agef=personClass4.getDeclaredField("age"); 85 agef.setAccessible(true);//忽略验证修饰符 86 System.out.println(agef.get(p4));//获得p4的年龄 87 agef.setInt(p4, 11);//设置p4的年龄值 88 System.out.println(p4); 89 } 90 }
时间: 2024-10-13 02:41:52