前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >第89节:Java中的反射技术

第89节:Java中的反射技术

作者头像
达达前端
发布2019-07-03 15:21:13
4860
发布2019-07-03 15:21:13
举报
文章被收录于专栏:达达前端
第89节:Java中的反射技术

第89节:Java中的反射技术

反射技术是动态的获取指定的类,和动态的调用类中的内容(没有类前就可以创建对象,将对象的动作完成,这就是动态的获取指定的类)。

配置文件把具体实现的类名称定义到配置文件中。

反射技术的作用可以提高程序的扩展性。

Object

clone() 用于创建并返回此对象的一个副本

equals(Object obj) 用于指示其他某个对象是否与这个对象“相等”

getClass() 用于返回此Object的运行时类

hashCode() 用于返回该对象的哈希码值

notify() 用于唤醒在此对象监视器上等待的单个线程

notifyAll() 用于唤醒在此对象监视器上等待的单个线程

notifyAll() 用于唤醒在此对象监视器上等待的所有线程

toString() 用于返回该对象的字符串

要获取某文件中的成员,就要先获取某文件的对象

代码语言:javascript
复制
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();
 // 获取创建字节码对象所表示的类的实例
 
}
代码语言:javascript
复制
pulic T newInstance() throws InstantiationException, IllegalAccessException
创建此Class对象所表示的类的一个实例,对一个带有一个空参数列表的new表达式实例化这个类。

获取构造函数

代码语言:javascript
复制
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);
}

获取字段

代码语言:javascript
复制
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);
}
代码语言:javascript
复制
getField
public Field getField(String name) thows NoSuchFieldException, SecurityException.
返回一个Field对象。

NoSuchFieldException
如果没有找到带有指定名的字段会报这个错
NullPointerException
如果name为null会报这个错

获取方法

代码语言:javascript
复制
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对象,把创建对象的动作做完,接着才在配置文件中添加哪个类。

当我们使用的类不明确时,通过配置文件告诉应用程序即可。

代码语言:javascript
复制
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 根类加载器

代码语言:javascript
复制
路径 jre/lib/rt.jar文件 核心类的加载

Extension ClassLoader 扩展类加载器

代码语言:javascript
复制
路径 jre/lib/ext目录 jar包的加载

System ClassLoader 系统类加载器

代码语言:javascript
复制
jvm启动时加载来自java命令的class文件

反射

代码语言:javascript
复制
源文件 -> 字节码 -> 创建对象
代码语言:javascript
复制
Class cla = Class.forName("类名"); // 读取配置文件
代码语言:javascript
复制
Class cla = Person.class
代码语言:javascript
复制
Person p = new Person(); Class cla = p.getClass();

三种方式:

代码语言:javascript
复制
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()读取配置文件

代码语言:javascript
复制
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();
}

通过反射获取带参构造方法

代码语言:javascript
复制
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);
 }
}

反射获取成员变量

代码语言:javascript
复制
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, "李四");
 }
}

获取方法

代码语言:javascript
复制
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);
 }
}

泛型

代码语言:javascript
复制
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改属性值

代码语言:javascript
复制
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);
 }
}
代码语言:javascript
复制
public static void main(String[] args){
 
 }

class Student {
 private String name;
 private int age;
 ...
}

反射

代码语言:javascript
复制
public class Demo {
 public void run() {
  System.out.println("dashucoding");
 }
}
代码语言:javascript
复制
// 配置文件 获取这个名词并加载这个类
com.dashucoding.test.Demo
代码语言:javascript
复制
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();
}

动态代理

代码语言:javascript
复制
public interface User {
 public void add();
 public void delete();
}
代码语言:javascript
复制
public class UserImp implements User{
 @Override 
 public void add() {
  System.out.println("添加");
 }
 @Override
 public void delete(){
  System.out.println("删除");
 }
}
代码语言:javascript
复制
public class Test {
 public static void main(String[] args){
  UserImp ui = new UserImp();
  ui.add();
  ui.delete();
 }
}

动态代理,在程序运行中产生对象。

代码语言:javascript
复制
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h);
代码语言:javascript
复制
new ProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h);

invoke(Object proxy, Method nethod, Object[] args);
代码语言:javascript
复制
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;
 }
}
代码语言:javascript
复制
MyInvocationHandler m = new MyInvocationHandler(si);
Student s = (Student)Proxy.newProxyInstance(ui.getClass().getClassLoader(), ui.getClass().getInterfaces(), m);

结言

好了,欢迎在留言区留言,与大家分享你的经验和心得。

感谢你学习今天的内容,如果你觉得这篇文章对你有帮助的话,也欢迎把它分享给更多的朋友,感谢。

作者简介

达叔,理工男,简书作者&全栈工程师,感性理性兼备的写作者,个人独立开发者,我相信你也可以!阅读他的文章,会上瘾!,帮你成为更好的自己。长按下方二维码可关注,欢迎分享,置顶尤佳。

感谢!承蒙关照!您真诚的赞赏是我前进的最大动力!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.02.26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 结言
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档