第一个阶段
第二个阶段
![第三个阶段
反射-获取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); // 私有方法必须设置访问权限为true
m1.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();