- 1. 概念
- 2. 获取成员变量
- 2.1 获取public修饰的成员变量
- 2.2 获取已声明的属性
- 3.获取方法
- 3.1 获取public修饰的,和继承自父类的 方法
- 3.2 获取本类中定义的方法
- 4. 获取构造器
- 4.1 获取所有public修饰的构造器
- 4.2 获取本类中定义的构造器
- 5.jdk文件分析
- 5.1bin目录:
- 5.2 include:底层用的是C++写的
- 5.3 jre:运行环境
- 5.4 lib : 包含jar包
- 6、获取类名
第一个阶段
第二个阶段
![第三个阶段
反射-获取Class对象的三种方式:
反射:框架设计的灵魂。
1. 概念
官方解释:反射是指在程序运行过程中,动态的获取类的信息,并且访问
我们通过反射还是获取类的信息(属性,方法,构造方法),然后访问,只不过我们现在不再以new的方式获取
反射的好处:
1、可以在程序运行过程中,操作这些对象
2、可以解耦,提高程序的可
Java中反射相关的API都位于java.lang.reflect包下
万物皆对象
Class 类
Method 方法
Filed 属性
Constructor 构造方
2. 获取成员变量
2.1 获取public修饰的成员变量
getFields() 获取所有的public修饰的属性/成员变量
操作:(1)设置值;(2)获取值
getField(String name)根据名字获取单个属性对象
package com.qfedu.test1;import java.lang.reflect.Field;
/*** 获取public声明的所有的属性信息 并且访问* @author WHD**/
public class Student {public String name;public int age;public String address;public Student() {System.out.println("Student类的无参构造");}public static void main(String[] args) {try {// 根据包名+ 类名 (全限定名)获取类信息文件Class<?> stuClass = Class.forName("com.qfedu.test1.Student");// 调用Class类的newInstance方法 构造实例Object newInstance1 = stuClass.newInstance();Object newInstance2 = stuClass.newInstance();Object newInstance3 = stuClass.newInstance();// 通过Class对象获取到当前类所有的属性 返回值为字段数组Field [] fs = stuClass.getFields();for(Field f : fs) {System.out.println(f.getName());}// 根据字段名称获取到单个字段对象Field nameField = stuClass.getField("name");// 调用字段set方法 设置属性值nameField.set(newInstance2, "赵四");// 调用字段get方法 获取属性值System.out.println(nameField.get(newInstance2));Field ageField = stuClass.getField("age");ageField.set(newInstance1, 20);System.out.println(ageField.get(newInstance1));Field addressField = stuClass.getField("address");addressField.set(newInstance3, "象牙山");System.out.println(addressField.get(newInstance3));} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (NoSuchFieldException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();}}}
2.2 获取已声明的属性
getDeclaredFields() 获取所有已定义的属性对象 包括 private 默认 protected public
getDeclaredField(String name) 根据名字获取单个属性对象 可以是任意访问修饰符
package com.qfedu.test2;import java.lang.reflect.Field;/*** 获取到类中所有的属性* @author WHD**/
public class Person {private String name;int age;protected String address;public char sex;public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {Class<?> personClass = Class.forName("com.qfedu.test1.Person");Field[] fs = personClass.getDeclaredFields();for (Field field : fs) {System.out.println(field.getName() + "\t" +field.getType());}Object newInstance = personClass.newInstance();Field nameField = personClass.getDeclaredField("name");nameField.set(newInstance, "广坤");nameField.setAccessible(true);//暴力反射(不会报警告)System.out.println(nameField.get(newInstance));Field sexField = personClass.getDeclaredField("sex");sexField.set(newInstance, '男');System.out.println(sexField.get(newInstance));}
}
package com.qfedu.test2;
import java.lang.reflect.Field;
/*** 获取属性* getFields() 获取所有的public修饰的属性* getField(String name)根据名字获取单个属性对象* getDeclaredFields() 获取所有已定义的属性对象。包括 private 默认 protected public* getDeclaredField(String name) 根据名字获取单个属性对象 可以是任意访问修饰符 * @author WHD**/
public class TestPerson {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException {
// Person p = new Person();
// p.name = ""Class<?> personClass = Class.forName("com.qfedu.test1.Person");Field nameField = personClass.getDeclaredField("name");nameField.setAccessible(true); // 设置访问权限为true 表示忽略JVM非法访问异常System.out.println(nameField.getName() + nameField.getType());Object newInstance = personClass.newInstance();nameField.set(newInstance, "赵四");System.out.println(nameField.get(newInstance));}
}
3.获取方法
方法的三要素:方法名,返回值列表,参数值列表
确定一个方法的两要素:方法名,参数值列表
3.1 获取public修饰的,和继承自父类的 方法
getMethods() 获取本类所有public修饰的方法和继承父类的方法
getMethod() 获取单个的方法
package com.qfedu.test3;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class TestStudent {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {Class<?> studentClass = Class.forName("com.qfedu.test3.Student");Method[] methods = studentClass.getMethods();System.out.println(methods.length);for (Method method : methods) {System.out.println(method.getName());}Object newInstance = studentClass.newInstance();Method m1Method = studentClass.getMethod("m1");m1Method.invoke(newInstance);Method method = studentClass.getMethod("m1", String.class);method.invoke(newInstance, "赵四");Method method2 = studentClass.getMethod("m1", int.class);method2.invoke(newInstance, 330);Method method3 = studentClass.getMethod("m3", String.class,int.class);method3.invoke(newInstance, "赵四",22);}
}
3.2 获取本类中定义的方法
//获取单个本类中声明的方法。如果访问权限不足,可以使用此方法
getDeclaredMethod(String name,Class<?>…parameterTypes)
setAccessable(true);//暴力修改权限
getDeclaredMethods();// 获取所有本类中已定义的方法
package com.qfedu.test4;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class TestStudent {public static void main(String[] args) {try {Class<?> stuClass = Class.forName("com.qfedu.test4.Student");Method[] ms = stuClass.getDeclaredMethods();for (Method method : ms) {System.out.println(method.getName());}Object newInstance = stuClass.newInstance();Method m1 = stuClass.getDeclaredMethod("m1");m1.setAccessible(true); // 私有方法必须设置访问权限为truem1.invoke(newInstance);Method m2 = stuClass.getDeclaredMethod("m1", String.class);m2.invoke(newInstance, "赵四");Method m3 = stuClass.getMethod("m3", String.class,int.class);m3.invoke(newInstance, "广坤",20);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();}}
}
4. 获取构造器
4.1 获取所有public修饰的构造器
constructor的作用:创建对象
getConstructors() 获取public修饰的构造方法
getConstructor(Class … type) 获取单个的构造器对象
package com.qfedu.test5;
/*** 获取本类中定义的以public修饰的构造方法* @author WHD*/
public class Student {public String name;public int age;public String address;public Student() {System.out.println("Student类的无参构造");}public Student(String name, int age, String address) {this.name = name;this.age = age;this.address = address;System.out.println("三个参数的构造方法");}public Student(String name) {this.name = name;System.out.println("一个参数的构造方法");}public Student(String name, int age) {this.name = name;this.age = age;System.out.println("两个参数的构造方法");}
}
package com.qfedu.test5;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class TestStudent {public static void main(String[] args) {try {Class<?> stuClass = Class.forName("com.qfedu.test5.Student");Constructor<?>[] cs = stuClass.getConstructors();for (Constructor<?> c : cs) {System.out.println("名字" + c.getName() + "参数个数" + c.getParameterCount());}Constructor<?> constructor1 = stuClass.getConstructor();Object newInstance1 = constructor1.newInstance();Constructor<?> constructor2 = stuClass.getConstructor(String.class,int.class,String.class);Object newInstance2 = constructor2.newInstance("赵四",20,"象牙山");Constructor<?> constructor3 = stuClass.getConstructor(String.class);Object newInstance3 = constructor3.newInstance("广坤");} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}
}
4.2 获取本类中定义的构造器
getDeclaredConstructors() 获取本类中定义的所有的构造方法
getDeclaredConstructor() 获取本类中单个的构造方法
package com.qfedu.test6;
/*** 获取本类中定义的以public修饰的构造方法* @author WHD*/
public class Student {public String name;public int age;public String address;private Student() {System.out.println("Student类的无参构造");}Student(String name, int age, String address) {this.name = name;this.age = age;this.address = address;System.out.println("三个参数的构造方法");}protected Student(String name) {this.name = name;System.out.println("一个参数的构造方法");}public Student(String name, int age) {this.name = name;this.age = age;System.out.println("两个参数的构造方法");}
}
package com.qfedu.test6;import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;public class TestStudent {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {Class<?> stuClass = Class.forName("com.qfedu.test6.Student");Constructor<?>[] cs = stuClass.getDeclaredConstructors();System.out.println(cs.length);Constructor<?> cons1 = stuClass.getDeclaredConstructor();cons1.setAccessible(true);Object newInstance1 = cons1.newInstance();}
}
5.jdk文件分析
5.1bin目录:
执行文件javac、javadoc、Javaws、jcmd、jconsole、jdb控制台、jsadebugd、keytool生成证书
5.2 include:底层用的是C++写的
.h : C语言写的文件; win32 : 系统底层
5.3 jre:运行环境
5.4 lib : 包含jar包
Java.long、java.applet用于处理图形、fonts字体设置、security安全、Java核心jar包:rt.jar
6、获取类名
method.getName();//获取方法名
*Class.getName();//获取类名
String className = studentClass.getName();