反射
反射【框架设计的灵魂】:将类的各个组成部分封装为其他对象,这就是反射机制
好处:1.可以在程序运行过程中,操作这些对象
2. 可以解耦,提高程序的可拓展性
获取class对象的3种方式:
1.Class.forname(“全类名”);将字节码文件加载进内存,返回Class对象【多用于配置文件,将类名定义在配置文件中。读取对象,加载类】
2.类名.class:通过类名的属性class获取【多用于参数的传递】
3.对象.getClass:该方法在object中定义【多用于对象获取字节码的方式】
同一字节码文件(*.class)在一次程序运行中,只会被加载一次,不论通过哪一种 方式获取到的Class对象都是同一个
Class对象功能
获取功能:
1.获取成员变量们
Field getField(String name)
Field[] getFields() 获取所有public修饰的成员变量
Field getDeclaredField(String name)
Field[] getDeclaredFields() 获取所有成员变量
Field方法
Object get(Object obj) 【获取值】
void set(Object obj, Object value) 【设置传入对象值】
setAccessible(true)【暴力反射】 忽略访问权限修饰符的安全检查
2.获取构造方法们
Constructor<T> getConstructor(类<?>... parameterTypes)
Constructor con=personClass. getConstructor(String.class,int.class)
Constructor<?>[] getConstructors()
Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
Constructor<?>[] getDeclaredConstructors()
Constructor
【创建对象】
1.T newInstance(Object... initargs)
con.newInstance(“张三”,”23”)
2.如果使用空参构造方法创建对象,操作可以简化:Class对象的 newInstance方法
personClass.newInstance()
3.获取成员方法们
Method getMethod(String name, 类<?>... parameterTypes)
Method[] getMethods()
Method getDeclaredMethod(String name, 类<?>... parameterTypes)
Method[] getDeclaredMethods()
Method
执行方法
Object invoke(Object obj, Object... args) 【第一个参数是类对象】
4.获取全类名
String getName()
返回单位名称(类,接口,数组类,原始类型,或无效)的 类对象表示,作为一个 String。
创建一个配置文件pro.properties
className=cn.itcast.domin.Person
methodName=eat
1.加载配置文件
(1) 创建Properties对象 Properties p= new Properties();
(2) 加载配置文件,转换为一个集合
获取class目录下的配置文件
ClassLoder classloader=ReflectTest.class.getClassLoader();[获得该字节码文件的类加载器]
IntputSteam is=Classloader.getResourceAsStream(“pro.properties”);[获取资源所对应的字节流]
pro.load(i);
2.获取配置文件中定义的数据
String className = pro.getProperty(“className”);
String className = pro.getProperty(“methodName”);
3.加载该类进内存
Class cls = Class.forName(className);
4.创建对象
Object obj=cls.newInstance();
5.获取方法对象
Method method=cls.getMethod(methodName);
6.执行方法
method.invoke(obj);
【jvm记载类顺序测试】
package edu.xupt.reflect;
public class Demo1 {
static {
System.out.println("main方法将被执行");
}
public static void main(String[] args) throws ClassNotFoundException {
System.out.println(Son.z);
}
}
class Father{
static {
System.out.println("父类静态代码块");
}
public Father() {
System.out.println("父类初始化");
}
static int f=100;
}
class Son extends Father{
static {
System.out.println("子类静态代码块");
z=200;
}
static int z=100;
static final int N=1000;
public Son() {
System.out.println("子类初始化");
}
}
package edu.xupt.reflect;
public class Demo2 {
public static void main(String[] args) throws ClassNotFoundException {
System.out.println("获取系统类的加载器");
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
System.out.println("获取系统类加载器的父加载器-->拓展加载器");
ClassLoader parent = systemClassLoader.getParent();
System.out.println(parent);
System.out.println("获取拓展类加载器的父加载器-->根加载器");
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);
System.out.println(Demo2.class.getClassLoader());
Class<?> aClass = Class.forName("edu.xupt.reflect.Demo2");
System.out.println(aClass.getClassLoader());
System.out.println("检测JDK内置类是谁加载的");
System.out.println(Object.class.getClassLoader());
System.out.println(Class.forName("java.lang.ClassLoader" /*Object*/).getClassLoader());
System.out.println("获得系统类加载器可以加载的路径");
System.out.println(System.getProperty("java.class.path"));
/*
D:\Java\jdk1.8.0_212\jre\lib\charsets.jar;
D:\Java\jdk1.8.0_212\jre\lib\deploy.jar;
D:\Java\jdk1.8.0_212\jre\lib\ext\access-bridge-64.jar;
D:\Java\jdk1.8.0_212\jre\lib\ext\cldrdata.jar;
D:\Java\jdk1.8.0_212\jre\lib\ext\dnsns.jar;
D:\Java\jdk1.8.0_212\jre\lib\ext\jaccess.jar;
D:\Java\jdk1.8.0_212\jre\lib\ext\jfxrt.jar;
D:\Java\jdk1.8.0_212\jre\lib\ext\localedata.jar;
D:\Java\jdk1.8.0_212\jre\lib\ext\nashorn.jar;
D:\Java\jdk1.8.0_212\jre\lib\ext\sunec.jar;
D:\Java\jdk1.8.0_212\jre\lib\ext\sunjce_provider.jar;
D:\Java\jdk1.8.0_212\jre\lib\ext\sunmscapi.jar;
D:\Java\jdk1.8.0_212\jre\lib\ext\sunpkcs11.jar;
D:\Java\jdk1.8.0_212\jre\lib\ext\zipfs.jar;
D:\Java\jdk1.8.0_212\jre\lib\javaws.jar;
D:\Java\jdk1.8.0_212\jre\lib\jce.jar;
D:\Java\jdk1.8.0_212\jre\lib\jfr.jar;
D:\Java\jdk1.8.0_212\jre\lib\jfxswt.jar;
D:\Java\jdk1.8.0_212\jre\lib\jsse.jar;
D:\Java\jdk1.8.0_212\jre\lib\management-agent.jar;
D:\Java\jdk1.8.0_212\jre\lib\plugin.jar;
D:\Java\jdk1.8.0_212\jre\lib\resources.jar;
D:\Java\jdk1.8.0_212\jre\lib\rt.jar;
D:\Java\zhang\2019.11.23—注解\out\production\2019.11.23—注解;
D:\IntelliJ IDEA 2019.2.3\lib\idea_rt.jar
*/
}
}
【反射基本方法测试】
package edu.xupt.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Demo3 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
Class<?> c1 = Class.forName("edu.xupt.reflect.Student");
System.out.println("类名");
System.out.println(c1.getName());
System.out.println(c1.getSimpleName());
System.out.println("======================");
System.out.println("获得成员变量");
Field[] fields = c1.getFields();
for (Field field : fields) {
System.out.println(field);
}
fields = c1.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("======================");
Method[] methods = c1.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println(">>>>>>>>>>>>>>>>>>>>");
methods = c1.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("======================");
Constructor<?> constructor = c1.getConstructor(int.class, String.class, boolean.class);
System.out.println(constructor);
Class<String> stringClass = String.class;
System.out.println(stringClass);
}
}
class Student{
private int id;
private String name;
private boolean sex;
// public String name1;
public Student() {
}
public Student(int id, String name, boolean sex) {
this.id = id;
this.name = name;
this.sex = sex;
}
public Student(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public String setName(String name) {
return this.name = name;
}
private void show(){
System.out.println("show被调用");
}
public void show1(){
System.out.println("show1被调用");
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", sex=" + sex +
'}';
}
}
【单例模式的反射破坏】
package edu.xupt.desidn.singleton;
import java.awt.geom.FlatteningPathIterator;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class Demo6 {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
/* test1 test = new test1();
for (int i = 0; i < 100; i++) {
new Thread(test).start();
}*/
Constructor<Singleton6> Constructor = Singleton6.class.getDeclaredConstructor(null);
Constructor.setAccessible(true);
Singleton6 singleton6 = Constructor.newInstance();
Field flag = Singleton6.class.getDeclaredField("flag");
flag.setAccessible(true);
flag.set(singleton6,false);
Singleton6 singleton61 = Constructor.newInstance();
System.out.println(singleton6 == singleton61);
}
}
class Singleton6{
private static boolean flag= false;
private volatile static Singleton6 singleton6;
private Singleton6() {//[可以考虑直接抛异常,不允许进构造]
if (flag==false){
flag=true;
System.out.println("第一次进构造");}
else {throw new RuntimeException("不要想着用反射破坏我的单例");
}
}
public static Singleton6 getSingleton6() {
if (singleton6==null){
synchronized (Singleton6.class){
if (singleton6==null){
System.out.println("实例化");
singleton6 = new Singleton6();
}
}
}
return singleton6;
}
}
class test6 implements Runnable{
@Override
public void run() {
Singleton6.getSingleton6();
}
}

浙公网安备 33010602011771号