package com.part01; /** * 什么是反射: * java中的反射是指在运行时,可以探测字节码文件的 成员变量 成员方法 接口 构造方法,实例化对象,调方法,成员 * java执行的过程: * step1:java Hello 将字节码文件载入内存 * step2:检查(1)给的是不是字节码(2)是的话,是否符合字节码文件的规范(3)符合的话,检查里面有没有安全风险 * step3:为每个字节码生成一个class对象 java.lang.Class(描述字节码文件信息的类) * step4:初始化静态代码块,静态变量 * step5:执行入口方法main */ public class Demo01 { //如何得到java.lang.Class 对象 public static void main(String[] args) throws ClassNotFoundException { //方法一 类.class Class<String> clazz1=String.class; Class<Demo01> clazz2=Demo01.class; System.out.println(clazz1+"--->"+clazz2); //方法二 对象.getClass() Demo01 d1=new Demo01(); String s1=new String("abc"); Class clazz3=d1.getClass(); Class clazz4=s1.getClass(); System.out.println(clazz3+"--->"+clazz4); //方法三 Class.forName(全路径) Class clazz5=Class.forName("java.lang.String"); Class clazz6=Class.forName("java.awt.Color"); System.out.println(clazz5+"--->"+clazz6); //方法四 基本类型 Class clazz7=int.class; Class clazz8=Integer.TYPE;//基本类型对应的包装类,都有一个TYPE成员 Class clazz9=Integer.class; Class clazz10=Class.forName("java.lang.Integer"); System.out.println(clazz7==clazz8); System.out.println(clazz7==clazz9); System.out.println(clazz10==clazz9); } }
运行结果如下:
class java.lang.String--->class com.part01.Demo01
class com.part01.Demo01--->class java.lang.String
class java.lang.String--->class java.awt.Color
true
false
true
获得反射操作类实现的所有接口和父类
package com.part01; public class Demo02 { public static void main(String[] args) { Class clazz=String.class; //取得String类实现的所有接口 Class[] allinter=clazz.getInterfaces(); for(Class c:allinter) { System.out.println(c); } //取得String类的父类 Class superc=clazz.getSuperclass(); System.out.println(superc); } }
结果如下:
interface java.io.Serializable
interface java.lang.Comparable
interface java.lang.CharSequence
class java.lang.Object反射调用构造,方法,成员如下:
自定义Student类
package com.part01; public class Student { private int age; public String name; public Student() {this.name="lisa";this.age=20;} public Student(String name,int age) { this.name=name; this.age=age; } private Student(int age) {} public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "["+name+":"+age+"]"; } }
对构造的操作
package com.part01; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class Demo03 { public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Class clazz=Student.class; //Constructor<Student> []all=clazz.getConstructors();只得到public的构造方法 Constructor<Student> []all=clazz.getDeclaredConstructors();//得到所有构造方法,包括private for(Constructor con:all) { System.out.println(con); } //得到指定参数的构造方法 Constructor<Student> cons=clazz.getDeclaredConstructor(new Class[] {String.class,int.class});//可变长形参 // java.lang.reflect包下的Constructor类中的newInstance方法 //使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。 // Student stu=cons.newInstance(new Object[] {"李四" ,23}); //System.out.println(stu); //为了实例化对象方便java.lang.Class有一个newInstance方法调用不带参数的构造方法,创建此 Class对象所表示的类的一个新实例。 Student stu1=(Student)clazz.newInstance();//调用不带参数的构造方法 System.out.println(stu1); } }
结果如下:
private com.part01.Student(int)
public com.part01.Student(java.lang.String,int)
public com.part01.Student()
[lisa:88]对方法的操作
package com.part01; import java.lang.reflect.Method; public class Demo04 { public static void main(String[] args)throws Exception { Class<Student> clazz=Student.class; Student stu=clazz.newInstance(); System.out.println("------------所有的方法---------------------"); Method [] all=clazz.getDeclaredMethods(); for(Method m:all) { System.out.println(m); } System.out.println("------------找指定参数的方法---------------------"); Method setname=clazz.getMethod("setName", new Class[] {String.class}); Method setage=clazz.getMethod("setAge", new Class[] {int.class}); //调用方法 //相当于stu.setName("lili") // setname.invoke(stu, new Object[] {"lili"}); // setage.invoke(stu, new Object[] {26}); setname.invoke(stu, "lili"); setage.invoke(stu, 26); System.out.println(stu); } }
结果如下:
------------所有的方法---------------------
public java.lang.String com.part01.Student.toString()
public java.lang.String com.part01.Student.getName()
public void com.part01.Student.setName(java.lang.String)
public void com.part01.Student.setAge(int)
public int com.part01.Student.getAge()
------------找指定参数的方法---------------------
[lili:26]
对成员的操作
package com.part01; import java.lang.reflect.Field; import java.lang.reflect.Modifier; public class Demo05 { public static void main(String[] args) throws Exception { Class clazz=Class.forName("com.part01.Student"); Student stu=(Student)clazz.newInstance(); Field all[]=clazz.getDeclaredFields(); for(Field f:all) { System.out.println(f+"--"+f.getType()+"--"+Modifier.isPublic(f.getModifiers())); } System.out.println("---得到指定filed----------"); Field fname=clazz.getDeclaredField("name"); fname.setAccessible(true);//私有成员设值 fname.set(stu, "小明");//给成员设值 System.out.println(stu); //调用成员的值 Object re=fname.get(stu);//stu.getName() System.out.println(re); } }
结果如下:
private int com.part01.Student.age--int--false
public static java.lang.String com.part01.Student.name--class java.lang.String--true
---得到指定filed----------
[小明:88]
小明