美文网首页
java——反射机制初级应用

java——反射机制初级应用

作者: 这颗螺丝钉姓赵 | 来源:发表于2017-03-21 15:31 被阅读0次

反射,一种计算机处理方式。是程序可以访问、检测和修改它本身状态或行为的一种能力(百度百科)。
在很多时候我们示例话对象的时候是通过一个关键字new来实现的,并对类的成员进行操作。而反射是通过一个特殊的类的类型来实现我们要对一个类的所有操作.
实例化一个Class类对象方法:
• public static Class<?> forName(String className)
【该方法的前提是知道一个类的全名(包名.类名)】
•public final Class<?> getClass()
【该方法可以获取类的Class类型的对象,但是前提是要先实例化类的本类对象,之后使用本类对象的getClass()方法获取】
•直接使用“类名称.class”
示例:

/-/工具类,上下文会用到:

package com.zhaoqiang.reflex;

public class Person {
    private String name;
    private int age;
    
    public Person(){}
    
    public Person(String name){
        this.name = name;
    }
    
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    
    public void say(){
        System.out.println("我是中国人,我说中文");
    }
    
    public void say(String str){
        System.out.println("狗娃是楚国人,它会背楚辞");
    }
    
    private void eat(){
        System.out.println("北方吃面条,南方吃米饭,西红柿放盐");
    }
    
}

package com.zhaoqiang.reflex;

import java.util.Date;

public class Demo1 {

    public static void main(String[] args) {
        
        //第一种: 实例化一个本类对象
        Date date = new Date();
        Class<?> cls1 = date.getClass();
    
      // Person类是自己定义的类
    
        // 第二种:获取类的全名(虚拟路径:包名.类名)
        // 此方法会抛出一个异常ClassNotFoundException
        try {
            Class<?> cls2 = Class.forName("/com.zhaoqiang.reflex.Person");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        // 第三种:通过类名实例化一个Class对象
        Class<?> cls3 = Person.class;
        
    }

}

创建了Class类对象我们就可以通过Class类对象来创建一个本类对象。
•public T newInstance() throws InstantiationException,
示例:

package com.zhaoqiang.reflex;

import java.util.Date;

public class Demo1 {

    public static void main(String[] args) throws Exception {
        
        //第一种: 实例化一个本类对象
//      Date date = new Date();
//      Class<?> cls1 = date.getClass();
        
        // 第二种:获取类的全名(虚拟路径:包名.类名)
        // 此方法会抛出一个异常ClassNotFoundException
        try {
            Class<?> cls2 = Class.forName("com.zhaoqiang.reflex.Person");
            
            // 通过Class对象实例化Person对象
            Person per = (Person)cls2.newInstance();
            System.out.println(per.toString());
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        // 第三种:通过类名实例化一个Class对象
//      Class<?> cls3 = Person.class;
        
        
        // 通过Class对象创建一个本类对象
        
        
    }

}

下面是一个简单工厂类使用反射来实现。
示例:

package com.zhaoqiang.reflex;

interface Comput{
    public abstract void say();
}

class HS implements Comput{
    @Override
    public void say() {
        System.out.println("正在使用hs电脑");
    }
}

class DE implements Comput{
    @Override
    public void say() {
        System.out.println("正在使用de电脑");
    }
}


class Factory{
    public static Comput getInstance(String className){
        
        try {
            Class<?> cls = Class.forName(className);
            return (Comput) cls.newInstance();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
        return null;
    }
}

public class Demo2 {
    public static void main(String[] args) {
        Comput cp = Factory.getInstance("com.zhaoqiang.reflex.HS");
        cp.say();
    }
}

通过Class对象实例化了类对象,一个类对象可能有很多个构造方法,如果类中没有默认构造函数,那么使用上的方法实例化对象就会报错。下面是通过Class对象获取类的构造函数方法:
•public Constructor<T> getConstructor(Class<?>... parameterTypes)
【获取指定的构造方法】

•public Constructor<?> [] getConstructors() throws SecurityException
【获取所有的构造方法】
示例:

package com.zhaoqiang.reflex;

import java.lang.reflect.Constructor;

public class Demo3 {
    public static void main(String[] args) throws Exception {
        Class<?> cls = Person.class;
        
        // 获取一个无参的构造方法
        Constructor<?> cons = cls.getConstructor();
        
        // 获取指定的构造函数
        Constructor<?> cons2 = cls.getConstructor(String.class);
        Person per1 = (Person)cons2.newInstance("张三");
        
        // 获取两个参数的指定构造函数
        Constructor<?> cons3 = cls.getConstructor(String.class,int.class);
        Person per2 = (Person)cons3.newInstance("李四",18);
        
        
        // 获取所有的构造方法
        Constructor<?> consarray[] = cls.getConstructors();
        
        // 特别注意:所有获取的构造方法排序是从构造方法中参多的排在第一个
    }
}

通过反射调用类中普通方法:
•public Method getMethod(String name,Class<?>... parameterTypes)
【获取指定参数的普通方法,第一个参数是方法名称,参数列表的Class类类型】

•public Method[] getMethods() throws SecurityException
【获取所有的普通方法】

这里出现了一个新的类:Mehtod类,该类专门对象普通方法进行操作,要执行普通方法则需要该类中的一个方法:
•public Object invoke(Object obj, Object... args)
【执行该方法,第一个参数是对象的名称,第二个参数是方法中传递的参数】
示例:

package com.zhaoqiang.reflex;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class Demo4 {
    public static void main(String[] args) throws Exception {
        Class<?> cls = Person.class;
        
        Constructor<?> con = cls.getConstructor(String.class,int.class);
        
        Person per = (Person) con.newInstance("狗娃",16);
        
        
        // 无参
        Method mt = cls.getMethod("say");
        mt.invoke(per);
        
        // 有参
        Method mt2 = cls.getMethod("say", String.class);
        mt2.invoke(per, "狗娃");
        
          // 获取所有的方法
        Method[] mt3 = cls.getMethods();
    }
}

通过反射调用类中成员变量:
•public Field getDeclaredField(String name)
【获取指定的属性】

  •public Field[] getDeclaredFields() throws SecurityException
【获取所有的属性】

在上面的方法中又出现了一个新的类 Field,该类是专门对属性进行操作的,在该了中又提供了两个方法
|- public String getName()【获取属性的名称】
|- public Object get(Object obj)【获取属性对应的值】
|- public void set(Object obj, Object value)【为属性设置值】
示例:

package com.zhaoqiang.reflex;

import java.lang.reflect.Field;

public class Demo5 {

    public static void main(String[] args) throws Exception {
        Class<?> cls = Person.class;
        Person per = (Person) cls.newInstance();
        
        // 获取指定的属性
        Field f = cls.getDeclaredField("name");
        
        // 获取所有的属性
        Field[] farray = cls.getDeclaredFields();
        
        // 获取属性名称
        farray[0].getName();
        
        
        // 取消private封装
        f.setAccessible(true);
        
        // 设置值
        f.set(per, "狗娃");
        
        // 获取属性对于的值
        farray[0].get(per);
        
        System.out.println(per.getName());
    }

}

java反射的一些简单应用:
示例一:

package com.zhaoqiang.reflex;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

/*
 * 要求将Person 对象中的属性以及属性值转换成一个指定字符串格式:
 * "person":"{"name":"smith","age":"123"}"
 * */

public class Test1 {

    public static void main(String[] args) throws Exception {
        // 获取Class对象
        Class<?> cls = Person.class;
        
        // 获取两个参数的构造函数
        Constructor<?> con = cls.getConstructor(String.class,int.class);
        
        // 实例化一个Person对象
        Person per = (Person) con.newInstance("狗娃",100);
        
        // 获取Person类中所有属性
        Field[] f = cls.getDeclaredFields();
        
        // 声明一个StringBuffer对象
        StringBuffer sb = new StringBuffer();
        sb.append("\"Person\":\"{\"");
        
        for(int i=0; i<f.length; i++){
            
            // 解除封装
            f[i].setAccessible(true);
            sb.append("\""+f[i].getName()+"\":");
            sb.append("\""+f[i].get(per)+"\"");
        }
        sb.delete(sb.length()-1, sb.length());
        sb.append("};");
        System.out.println(sb);
        
    }

}

package com.zhaoqiang.reflex;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/*
 * 要求将Person 对象中的属性以及属性值转换成一个指定字符串格式:
 * "person":"{"name":"smith","age":"123"}"
 * */

public class Test1 {

    public static void main(String[] args) throws Exception {
        // 获取Class对象
        Class<?> cls = Person.class;
        
        // 获取两个参数的构造函数
        Constructor<?> con = cls.getConstructor(String.class,int.class);
        
        // 实例化一个Person对象
        Person per = (Person) con.newInstance("狗娃",100);
        
        // 获取Person类中所有属性
        Field[] f = cls.getDeclaredFields();
        
        // 声明一个StringBuffer对象
        StringBuffer sb = new StringBuffer();
        sb.append("\"Person\":\"{\"");
        
        for(int i=0; i<f.length; i++){
            
            // 解除封装
//          f[i].setAccessible(true);
            // 不解除封装,通过方法名获取数据
            Method mt = cls.getMethod(initCap(f[i].getName())); // 去的属性对应的get方法
            
            sb.append("\""+f[i].getName()+"\":");
//          sb.append("\""+f[i].get(per)+"\"");
            sb.append("\""+mt.invoke(per)+"\"");
        }
        sb.delete(sb.length()-1, sb.length());
        sb.append("};");
        System.out.println(sb);
        
    }
    
    public static String initCap(String name){
        return "get"+name.substring(0,1).toUpperCase()+name.substring(1);
    }

}

相关文章

  • 反射之一

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • 反射之二

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • java——反射机制初级应用

    反射,一种计算机处理方式。是程序可以访问、检测和修改它本身状态或行为的一种能力(百度百科)。在很多时候我们示例话对...

  • 反射之三

    总结内容源自以下文章 粗浅看java反射机制 反射机制应用实践 谈谈java反射机制 Java Reflectio...

  • Chapter 13 . 反射机制

    阅读原文 Chapter 13 . 反射机制 13.1 Java反射机制研究及应用 Java Reflection...

  • Java反射机制入门

    Java反射机制入门 一、什么是反射 JAVA反射机制(The JAVA reflection mechanism...

  • Java基础之反射

    Java基础之—反射(非常重要)Java中反射机制详解Java进阶之reflection(反射机制)——反射概念与...

  • java反射机制

    java的反射机制 1 JAVA的反射机制是什么?反射机制能做什么?反射机制的优点与缺点2 认识 Class...

  • Java中反射的用途

    Java的反射机制是Java特性之一,反射机制是构建框架技术的基础所在。灵活掌握Java反射机制,对大家以后学习框...

  • 详解Java反射机制(Reflection)

    详解Java反射机制(Reflection) 反射机制的作用 JAVA反射机制是在运行状态中,对于任意一个类,都能...

网友评论

      本文标题:java——反射机制初级应用

      本文链接:https://www.haomeiwen.com/subject/ohbunttx.html