java反射

Posted 冰叔博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java反射相关的知识,希望对你有一定的参考价值。

           冰叔现在还在公司,虽然我是一个实习生,但是也能明白程序员为什么那么晚睡,也许有的人是为了自己的梦想,而有的人却是为了其他人的梦想,现在的的世界有着数不清的程序,但是好的程序却没几个。有的软件即使用的人很少但是他依旧很美。我经常晚上行走在城市中,自己感觉晚上的城市是最美的,它没有了白天的嘈杂,没有白天的拥挤,剩下的就是蟋蟀的叫声,和偶尔的汽车声,最美的还是城市的灯光了。

           冰叔总爱写写心情,如果大家不愿意看的话可以和我说,我可以写在我的日记里。

          不多说了,今天我学习了反射顺便把自己写的代码放在这里。方便大家查看,最好学习一下这些东西。

 

一、目录结构。

二、Demo文件

package com.xxx.demo;

import com.sun.xml.internal.ws.api.model.ExceptionType;
import com.xxx.handler.MyInvocationHandler;
import com.xxx.pojo.Person;
import com.xxx.service.UserService;
import com.xxx.service.impl.UserServiceImpl;
import org.junit.Test;

import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author:hsj
 * @Date:15:32 2017/7/27
 * @Description:java反射机制的学习
 */
public class Demo {

    //该方法通过反射得到类名和完整包名
    @Test
    public void fun() {
        Person p = new Person();       //创建了一个对象
        System.out.println(p.getClass().getName());
    }

    //实例化class类对象
    @Test
    public void fun2() throws Exception {
        Class<?> class2 = null;
        Class<?> class3 = null;
        Class<?> class4 = null;

        //一般采用这种形式
        class2 = Class.forName("com.xxx.pojo.Person");
        class3 = new Person().getClass();
        class4 = Person.class;
        System.out.println("类名称  " + class2.getName());
        System.out.println("类名称  " + class3.getName());
        System.out.println("类名称  " + class4.getName());
    }

    //获取一个对象的父类与实现接口
    @Test
    public void fun3() throws Exception {
        Class<?> class2 = Class.forName("com.xxx.pojo.Student"); //得到一个对象
        Class<?> parentClass = class2.getSuperclass();
        System.out.println(class2.getSuperclass().getName());   //得到父类的完整类名


        Class<?> class3 = Class.forName("com.xxx.service.impl.UserServiceImpl");
        Class<?> inters[] = class3.getInterfaces();
        for (int i = 0; i < inters.length; i++) {
            System.out.println(inters[i].getName());
        }
    }

    //获取某个类的所有构造函数
    @Test
    public void fun4() throws Exception {
        Class<?> class2 = Class.forName("com.xxx.pojo.Person");
        Class<?> class3 = Class.forName("com.xxx.pojo.Student");

        //第一种方式通过反射实例化一个对象
        Person p = (Person) class2.newInstance();
        p.setAge(20);
        p.setName("hsj");
        p.setHeight(175);
        p.setSex("男");

        System.out.println(p);

        Constructor<?> cons[] = class2.getConstructors();

        //得到所有构造函数
        for (int i = 0; i < cons.length; i++) {
            Class<?> clazz[] = cons[i].getParameterTypes();  //得到参数类型
            System.out.print("cons[" + i + "](");
            for (int j = 0; j < clazz.length; j++) {
                if (j == clazz.length - 1) {
                    System.out.print(clazz[j].getName());
                } else {
                    System.out.print(clazz[j].getName() + ",");
                }

            }
            System.out.println(")");
        }


        Person p2 = (Person) cons[0].newInstance("hsj", 20, "男", 175);
        Person p3 = (Person) cons[1].newInstance("hsj", 20, "男");
        Person p4 = (Person) cons[2].newInstance("hsj");
        System.out.println(p2);
        System.out.println(p3);
        System.out.println(p4);
    }

    //获取某个类的全部属性
    @Test
    public void fun5() throws Exception {
        System.out.println("===============本类属性===============");
        Class<?> tClass = Class.forName("com.xxx.pojo.Person");
        Class<?> tClass2 = Class.forName("com.xxx.pojo.Student");
        Field[] declaredFields = tClass.getDeclaredFields();      //获取所有字段
        for (int i = 0; i < declaredFields.length; i++) {
            int modifiers = declaredFields[i].getModifiers();     //修饰符
            String priv = Modifier.toString(modifiers);           //修饰符
            Class<?> type = declaredFields[i].getType();          //字段类型
            System.out.println(priv + "  " + type.getName() + "   " + declaredFields[i].getName() + ";");
        }

        System.out.println("===============实现的接口或者父类属性===============");
        Field[] fields = tClass2.getFields();   //此方法只能获取public的字段
        for (int j = 0; j < fields.length; j++) {
            int modifiers = fields[j].getModifiers();        //返回修饰符对应的整数
            String modifier = Modifier.toString(modifiers);  //得到修饰符
            Class<?> type = fields[j].getType();
            System.out.println(modifier + "   " + type.getName() + "   " + fields[j].getName() + ";");
        }
    }

    //获取某个类的全部方法
    @Test
    public void fun6() throws Exception {

        Class<?> class2 = Class.forName("com.xxx.service.impl.UserServiceImpl");
        Method[] methods = class2.getMethods();   //得到所有方法
        for (Method m : methods) {
            int mo = m.getModifiers(); //修饰符
            String modifie = Modifier.toString(mo);
            Class<?> returnType = m.getReturnType();//得到返回值类型
            Parameter[] parameters = m.getParameters();
            System.out.print(modifie + "   ");
            System.out.print(returnType.getName() + "   ");
            System.out.print(m.getName() + "(");
            for (int i = 0; i < parameters.length; i++) {
                System.out.print(parameters[i].getName() + " " + "arg" + i);
                if (i < parameters.length - 1) {
                    System.out.print(",");
                }
            }

            Class<?>[] exceptionTypes = m.getExceptionTypes();   //得到异常
            if (exceptionTypes.length > 0) {
                System.out.print(")  throws ");
                for (int i = 0; i < exceptionTypes.length; i++) {
                    System.out.print(exceptionTypes[i].getName());
                    if (i < exceptionTypes.length - 1) {
                        System.out.print(",");
                    }
                }
            } else {
                System.out.print(")");
            }
            System.out.println("");

        }
    }

    //通过反射调用方法
    @Test
    public void fun7() throws Exception {
        Class<?> clazz = Class.forName("com.xxx.service.impl.UserServiceImpl");
        Method method = clazz.getMethod("addUser");   //根据名字的到方法
        method.invoke(clazz.newInstance()); //调用方法

        Method hello = clazz.getMethod("hello", String.class, int.class);
        Object hsj = hello.invoke(clazz.newInstance(), "hsj", 20);
        System.out.println(hsj.toString());

    }

    //通过反射操作某个类的属性
    @Test
    public void fun8() throws Exception {
        Class<?> class2 = Class.forName("com.xxx.pojo.Person");
        Object obj = class2.newInstance();
        Field name = class2.getDeclaredField("name");
        Field age = class2.getDeclaredField("age");
        name.setAccessible(true);
        age.setAccessible(true);
        name.set(obj, "hsj");
        age.set(obj, 20);
        System.out.println(name.get(obj));
        System.out.println(age.get(obj));

    }

    //反射机制的动态代理
    @Test
    public void fun9() {
        MyInvocationHandler demo = new MyInvocationHandler();
        UserService userService = (UserService) demo.bind(new UserServiceImpl());
        userService.addUser();
    }

    //在泛型为Integer的ArrayList中存放一个String类型的对象。
    @Test
    public void fun10() throws Exception {
        List<Integer> list = new ArrayList<>();
        Method method = list.getClass().getMethod("add", Object.class);
        method.invoke(list, "生命在于运动!");
        System.out.println(list.get(0));
    }

    //通过反射获得并修改数组信息
    @Test
    public void fun11() {
        int[] array = {1, 2, 3, 4, 5, 6, 7};
        Class<?> demo = array.getClass().getComponentType();
        System.out.println("数组的类型" + demo.getName());
        System.out.println("数组长度 " + Array.getLength(array));
        System.out.println("数组的第一个元素  " + Array.get(array, 0));
        Array.set(array, 0, 100);
        System.out.println("修改数组的元素:" + Array.get(array, 0));
    }


    //通过反射修改数组的大小
    @Test
    public void fun12() {
       int[] temp={1,2,3,4,5,6,7};
       int[] newtemp=(int[]) arrayInc(temp,15);
       print(newtemp);
       String[] str={"a","b","c"};
       String[] str2=(String[]) arrayInc(str,8);
       print(str2);
    }

    //修改数组的大小
    public static Object arrayInc(Object obj, int len) {
        Class<?> arr = obj.getClass().getComponentType(); //
        Object newArr = Array.newInstance(arr, len);
        int co=Array.getLength(obj);
        System.arraycopy(obj,0,newArr,0,co);
        return newArr;
    }

    //打印
    public static void print(Object obj){
        Class<?> c=obj.getClass();
        if(!c.isArray()){
            return;
        }
        System.out.println("数组的长度:"+Array.getLength(obj));
        for (int i = 0; i <Array.getLength(obj) ; i++) {
            System.out.print(Array.get(obj,i)+" ");
        }
        System.out.println();
    }

}

 

MyInvocationHandler文件
package com.xxx.handler;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Author:hsj
 * @Date:15:30 2017/7/28
 * @Description:
 */
public class MyInvocationHandler implements InvocationHandler {
    private Object obj=null;

    public Object bind(Object obj){
        this.obj=obj;
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object temp=method.invoke(this.obj,args);
        return temp;
    }
}

/**
 * 在java中有三种类类加载器。
 *
 * 1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。
 *
 * 2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jrelibext目录中的类
 *
 * 3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。
 *
 * 如果想要完成动态代理,首先需要定义一个InvocationHandler接口的子类,已完成代理的具体操作。
 *
 * @author xsoftlab.net
 *
 */

Person文件

package com.xxx.pojo;

/**
 * @Author:hsj
 * @Date:15:35 2017/7/27
 * @Description:这是一个实体类
 */
public class Person {
    private String name;      //姓名
    private int age;          //年龄
    private String sex;       //性别
    private double height;    //身高
    public double money;

    public Person() {

    }

    public Person(String name) {
        this.name = name;
    }

    public Person(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }


    public Person(String name, int age, String sex, double height) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.height = height;
    }

    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 String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    //重写toString
    @Override
    public String toString() {
        return "Person{" +
                "name=\'" + name + \'\\\'\' +
                ", age=" + age +
                ", sex=\'" + sex + \'\\\'\' +
                ", height=" + height +
                \'}\';
    }
}

Student文件

package com.xxx.pojo;

import java.io.Serializable;

/**
 * @Author:hsj
 * @Date:16:12 2017/7/27
 * @Description:这是一个学生类继承了学生接口
 */
public class Student extends Person implements Serializable {
    private String stuNo;     //这是学号
    public double score;      //分数

    //空构造函数
    public Student(){

    }

    //构造函数
    public Student(String stuNo) {
        super();
        this.stuNo = stuNo;
    }

    public String getStuNo() {
        return stuNo;
    }

    public void setStuNo(String stuNo) {
        this.stuNo = stuNo;
    }

    //说英语方法
    public void sayEnglish(){
        System.out.println("I am a student i love say english , aare you ok?");
    }

    //重写toString

    @Override
    public String toString() {
        System.out.println("I am a student");
        return "you are very good";
    }
}

UserService文件

package com.xxx.service;

/**
 * @Author:hsj
 * @Date:16:17 2017/7/27
 * @Description:这是一个UserService接口
 */
public interface UserService {

    //添加用户
    void addUser();

    //修改用户
    void uodateUser();

    //查找用户
    void findUser();

    //删除用户
    void deleteUser();


}

UserServiceImpl文件

package com.xxx.service.impl;

import com.xxx.service.UserService;

import java.io.Serializable;

/**
 * @Author:hsj
 * @Date:16:20 2017/7/27
 * @Description:这是UserService的实现类
 */
public class UserServiceImpl implements UserService, Serializable {
    @Override
    public void addUser() {
        System.out.println("成功添加了一个用户");
    }

    @Override
    public void uodateUser() {
        System.out.println("用户信息修改成功");
    }

    @Override
    public void findUser() {
        System.out.println("成功查找到该用户");
    }

    @Override
    public void deleteUser() {
        System.out.println("删除成功");
    }

    private void sum() {
        System.out.println("这是一个统计数据使用的内部方法");
    }

    public String hello(String name, int age) {
        System.out.println("我是:" + name + "   年龄:" + age);
        return "i am a student";
    }

}

 

以上是关于java反射的主要内容,如果未能解决你的问题,请参考以下文章

反射机制入门

反射机制入门

反射机制入门

使用反射在外部JAR / CLASS上调用包含Hibernate事务的方法(Java EE)

为啥我的 Ray March 片段着色器反射纹理查找会减慢我的帧速率?

OpenGL片段着色器不照亮场景