第89节:
Java
中的反射技术java
反射技术是动态的获取指定的类,和动态的调用类中的内容(没有类前就能够建立对象,将对象的动做完成,这就是动态的获取指定的类)。web
配置文件把具体实现的类名称定义到配置文件中。jvm
反射技术的做用能够提升程序的扩展性。ide
Object
类svg
clone()
用于建立并返回此对象的一个副本函数
equals(Object obj)
用于指示其余某个对象是否与这个对象“相等”学习
getClass()
用于返回此Object
的运行时类ui
hashCode()
用于返回该对象的哈希码值this
notify()
用于唤醒在此对象监视器上等待的单个线程线程
notifyAll()
用于唤醒在此对象监视器上等待的单个线程
notifyAll()
用于唤醒在此对象监视器上等待的全部线程
toString()
用于返回该对象的字符串
要获取某文件中的成员,就要先获取某文件的对象
public class Person{ private String name; private int age; public Person(){ super(); } public Person(String name, int age){ super(); this.name = name; this.age = age; } } // 定义一个方法获取对象 public static void getClass(){ Person p = new Person(); Class class = p.getClass(); } public static void getClass(){ String className = "com.dashucoding.Person"; Class cla = Class.forName(className); Object obj = cla.newInstance(); // 获取建立字节码对象所表示的类的实例 }
pulic T newInstance() throws InstantiationException, IllegalAccessException 建立此Class对象所表示的类的一个实例,对一个带有一个空参数列表的new表达式实例化这个类。
获取构造函数
public static void getConstructorDemo() throws Exception { String className = "com.dashucodiing.Person"; Class cla = Class.forName(className); Constructor cons = cla.getConstructor(String.class, int.class); Object obj = cons.newInstance("dashu",12); }
获取字段
public static void getFieldDemo() throws Exception { String className = "com.dashucoding.Person"; Class cla = Class.forName(className); String fieldName = "age"; //获取字段 Field field = cla.getField(fieldName); System.out.printlnn(field); }
getField public Field getField(String name) thows NoSuchFieldException, SecurityException. 返回一个Field对象。 NoSuchFieldException 若是没有找到带有指定名的字段会报这个错 NullPointerException 若是name为null会报这个错
获取方法
public static void getMethodDemo() throws Exception { String className = "com.dashucoding.Person"; class cla = Class.forName(className); String methodName = "show"; Method method = cla.getMethod( methodName, String.class,int.class); Object obj = cla.newInstance(); method.invoke(obj, "dashu",12; }
反射技术是这样的之前先有类,才new
对象,如今有了它以后,先new
对象,把建立对象的动做作完,接着才在配置文件中添加哪一个类。
当咱们使用的类不明确时,经过配置文件告诉应用程序便可。
File configFile = new File("tempfile\\dashu.properties"); if(!configFile.exists()){ configFile.createNewFile(); } // 读取配置文件 FileReader fr = new FileReader(configFile); // 为了获取其中的键值信息 Properties prop = new Properties(); prop.load(fr); for(int x = 1; x<=prop.size(); x++){ String className = prop.getProperty("dashu"+x); Class cla = Class.forName(className); class.newInstance(); }
类加载的概述:
若是某个类被这个程序使用时,若是这个类没有被加载到内存中,就会由系统经过加载,链接,初始化三个步骤实现这个类并对其进行初始化。
加载是由内存进行class
文件的读取,简单来讲就是class
文件读入内存中,接着建立一个Class
对象,任何类被使用的时候,由系统创建一个Class
对象。(class
文件加载到内存中)
链接:验证,准备,解析
验证内部结构是否正确
准备是否为类的静态成员分配内存,并设置默认的初始化值
解析是将类的二进制数据中的符号引用换为直接引用哦
初始化进行初始化的操做
类加载器的概念
类加载器是把.class
文件加载到内存中,并生成对应的Class
对象。
类加载器的分类有哪些?
Bootstrap ClassLoader
根类加载器
Extension ClassLoader
扩展类加载器
System ClassLoader
系统类加载器
描述其做用:
Bootstrap ClassLoader
根类加载器
路径 jre/lib/rt.jar文件 核心类的加载
Extension ClassLoader
扩展类加载器
路径 jre/lib/ext目录 jar包的加载
System ClassLoader
系统类加载器
jvm启动时加载来自java命令的class文件
反射
源文件 -> 字节码 -> 建立对象
Class cla = Class.forName("类名"); // 读取配置文件
Class cla = Person.class
Person p = new Person(); Class cla = p.getClass();
三种方式:
Class cla = Class.forName("com.dashucoding.Person"); Class cla1 = Person.class; Person p = new Person(); Class cla2 = p.getClass(); System.out.println(cla = cla1); System.out.println(cla2 = cla1);
Class.forName()
读取配置文件
public class Demo { public static void main(String[] args) throws Exception { Juicer j = new Juicer(); j.run(new Apple()); } class Apple { public void squeeze() { System.out.println(); } } class Juicer { public void run(Apple a) { a.squeeze(); } } } interface Fruit { public void squeeze(); } class Apple implements Fruit { public void squeeze(){ System.out.println(""); } } public static void main(String[] args) throws ClassNotFoundException { Class cla1 = Class.forName("com.dashucodiing.Person"); Class cla2 = Person.class; Person p = new Person(); Class cla3 = p.getClass(); }
经过反射获取带参构造方法
package com.dashucoding.demo public class Demo { public static void main(String[] args) { Class clazz = Class.forName("com.dashucoding.bean.Person"); // Person p = (Person) clazz.newInstance(); Constructor c = clazz.getConstructor(String.class,int.class); Person p = (Person) c.newInstance("dashucoding",12); System.out.println(p); } }
反射获取成员变量
package com.dashucoding.demo public class Demo { public static void main(String[] args) { Class clazz = Class.forName("com.dashucoding.bean.Person"); Constructor c = clazz.getConstructor(String.class,int.class); Person p = (Person) c.newInstance("dashucoding",12); // 获取 Field f = clazz.getField("name"); f.set(p, "李四"); // Field f = clazz.getDeclaredField("name"); // f.set(p, "李四"); } }
获取方法
package com.dashucoding.demo public class Demo { public static void main(String[] args) { Class clazz = Class.forName("com.dashucoding.bean.Person"); Constructor c = clazz.getConstructor(String.class,int.class); Person p = (Person) c.newInstance("dashucoding",12); //获取 Method m = clazz.getMethod("say"); m.invoke(p); Method m2 = clazz.getMethod("say",int.class); m.invoke(p,12); } }
泛型
package com.dashucoding.demo public class Demo { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(); // list.add(1); Class clazz = Class.forName("java.util.ArrayList"); Method m = clazz..getMethod("方法名", Object.class); m.invoke(list,"abc"); System.out.println(list); } }
propertyName
改属性值
public class Tool { public void setProperty (Object obj, String propertyName, Object value) throws Exception { Class clazz = obj.getClass(); Field f = clazz.getDeclaredField(propertyName); f.setAccessible(true); f.set(obj, value); } }
public static void main(String[] args){ } class Student { private String name; private int age; ... }
反射
public class Demo { public void run() { System.out.println("dashucoding"); } }
// 配置文件 获取这个名词并加载这个类 com.dashucoding.test.Demo
public static void main(String[] args){ BufferedReader br = new BufferedReader(new FileReader("xxx.properties")); Class clazz = Class.forName(br.readLine()); Demo demo = (Demo) clazz.newInstance(); demo.run(); }
动态代理
public interface User { public void add(); public void delete(); }
public class UserImp implements User{ @Override public void add() { System.out.println("添加"); } @Override public void delete(){ System.out.println("删除"); } }
public class Test { public static void main(String[] args){ UserImp ui = new UserImp(); ui.add(); ui.delete(); } }
动态代理,在程序运行中产生对象。
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h);
new ProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h); invoke(Object proxy, Method nethod, Object[] args);
public class MyInvocationHandler implements InvocationHandler { private Object target; public MyInvocationHandler (Object target) { this.target = target; } @Override public Object invoke(Object proxy,Method method,object[] args) throws Throwable { method.invoke(target,args); return null; } }
MyInvocationHandler m = new MyInvocationHandler(si); Student s = (Student)Proxy.newProxyInstance(ui.getClass().getClassLoader(), ui.getClass().getInterfaces(), m);
好了,欢迎在留言区留言,与你们分享你的经验和心得。
感谢你学习今天的内容,若是你以为这篇文章对你有帮助的话,也欢迎把它分享给更多的朋友,感谢。
做者简介
达叔,理工男,简书做者&全栈工程师,感性理性兼备的写做者,我的独立开发者,我相信你也能够!阅读他的文章,会上瘾!,帮你成为更好的本身。长按下方二维码可关注,欢迎分享,置顶尤佳。
感谢!承蒙关照!您真诚的赞扬是我前进的最大动力!