通过案例一步学习理解java反射机制

java 反射机制

以下只是个人在学习反射过程中的笔记,如有错误请指出纠正。

1. 通过例子理解反射

  • 获取类的类类型的三种方法
package Reflect;

public class ClassReflect {
    public static void main(String[] args) {
        ClassReflect cr = new ClassReflect();
        //方法一:
        Class c = cr.getClass();
        //方法二:
        Class c1 =ClassReflect.class;//c1和c表示ClassReflect类的类类型
        //方法三:
        try {
            Class.forName("Reflect.ClassReflect");//常用
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    }
  • 通过类名获取类的实例及类的方法,类的构造方法
package Reflect;

public class Person {
    public Person(String name, int age) {
        this.age=age;
        this.name=name;
    }
    //无参构造函数一定得加上,否则报错空指针
    public Person(){

    }
     public Person(String name){
            this.name=name;
        }
        public Person(int age){
            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;
        }
        @Override
        public String toString(){
            return "["+this.name+"  "+this.age+"]";
        }
        private String name;
        private int age;
}

注意一下,当我们把Person中的默认的无参构造函数取消的时候,比如自己定义只定义一个有参数的构造函数之后,会出现错误

package Reflect;

import java.io.ObjectInputStream.GetField;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.StringTokenizer;

public class exampleOne {
public static void main(String[] args) throws  Exception {

    Class c = Class.forName("Reflect.Person");//获得person类
    Person per = (Person) c.newInstance();//person实例化
    Class exampleclass= Class.forName("Reflect.exampleOne");
    exampleOne example = (exampleOne) exampleclass.newInstance();
    try {
        Method m = exampleclass.getDeclaredMethod("print", int.class,int.class);//根据方法名及对象参数获取唯一的一个方法
        //Method m1 = c.getMethod("print", new Class[]{int.class,int.class});
        //c.getDeclaredMethod(name, parameterTypes); getMethod()是获取public方法,getDeclareMethod()是获取自己声明的方法
        int num =m.getModifiers();
        System.out.println(num);//当权限修饰符是public时,i是1,private 时,是2,protected时是4
         String priv = Modifier.toString(num);

        System.out.println("权限修饰符:"+priv);
        System.out.println("方法名:"+m.getName());
        m.invoke(example, 10,20);//方法的反射操作是,用m对象来进行方法调用
        System.out.println(" 获取构造方法及对应参数 ");
        Constructor[] constructor=c.getConstructors();

        for(int i=0;i<constructor.length;i++){
            System.out.print(Modifier.toString(constructor[i].getModifiers())+" ");;
            System.out.print (constructor[i].getName() +"(");
            Class[] param = constructor[i].getParameterTypes();
            for(int j=0;j<param.length;j++){
                System.out.print(param[j].getName()+" arg"+j);
                if(j<param.length-1){
                    System.out.print(", ");
                }
            }
            System.out.println(")");
        }
        Method[] method = c.getMethods();
        for(int i=0;i<method.length;i++){
            System.out.print(Modifier.toString(method[i].getModifiers())+" ");
            System.out.print (method[i].getReturnType()+" ");
            System.out.print (method[i].getName()+"(");
            Class<?>[] method_param = method[i].getParameterTypes();
            for(int j =0;j<method_param.length;j++){
                System.out.print (method_param[j].getName()+" arg"+j);
                if(j<method_param.length-1){
                    System.out.print (",");
                }

            }System.out.print (")");
            Class<?>[] exceptionType =method[i].getExceptionTypes();
            for(int k=0;k<exceptionType.length;k++){
                System.out.println("throws "+exceptionType[k].getName());
            }
        }

    } catch ( Exception   e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

}
    private void print(int a,int b){
        System.out.println("计算结果:"+(a+b));
    }

结果:

2

权限修饰符:private

方法名:print

计算结果:30

获取构造方法及对应参数

public Reflect.Person(java.lang.String arg0, int arg1)

public Reflect.Person(int arg0)

public Reflect.Person(java.lang.String arg0)

public Reflect.Person()

public int getAge()public void setAge(int arg0)public class java.lang.String toString()public class java.lang.String getName()public void setName(java.lang.String arg0)public final native class java.lang.Class getClass()public native int hashCode()public boolean equals(java.lang.Object arg0)public final native void notify()public final native void notifyAll()public final void wait()throws java.lang.InterruptedException

public final void wait(long arg0,int arg1)throws java.lang.InterruptedException

public final native void wait(long arg0)throws java.lang.InterruptedException

  • 调用其他类的set和get方法
package Reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class UseMethod {
    public static void main(String[] args) {
         Class<?> demo =null;
         Object obj =null;
                 try {
                    demo=Class.forName("Reflect.Person");
                } catch (ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                 try {
                    obj = demo.newInstance();

                } catch (InstantiationException | IllegalAccessException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                 setter(obj, "Age",20, int.class);
                 getter(obj, "Age");

    }
    public static void getter(Object obj,String attr){
        try {
            Method method = obj.getClass().getMethod("get"+attr);

                System.out.println(method.invoke(obj));

        } catch ( Exception  e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    public static void setter(Object obj, String attr, Object value,
            Class<?> type) {
        try {
            Method method = obj.getClass().getMethod("set"+attr,type);
     method.invoke(obj, value);
        } catch ( Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

输出结果:20

  • 通过反射操作属性,修改数组
package Reflect;

import java.lang.reflect.Array;
import java.lang.reflect.Field;

public class test01 {
    public static void main(String[] args) throws Exception {
        Class<?> demo = null;
        Object obj = null;

        demo = Class.forName("Reflect.Person");
        obj = demo.newInstance();

        Field field = demo.getDeclaredField("name");
        field.setAccessible(true);
        field.set(obj, "hlx");
        System.out.println(field.get(obj));
        test();
    }
    public static void test(){
          int[] temp={1,2,3,4,5};
            Class<?>demo=temp.getClass().getComponentType();
            System.out.println("数组类型: "+demo.getName());
            System.out.println("数组长度  "+Array.getLength(temp));
            System.out.println("数组的第一个元素: "+Array.get(temp, 0));
            Array.set(temp, 0, 100);
            System.out.println("修改之后数组第一个元素为: "+Array.get(temp, 0));
    }
}

输出结果:

hlx

数组类型: int

数组长度 5

数组的第一个元素: 1

修改之后数组第一个元素为: 100

  • 通过反射修改数组
package Reflect;

import java.lang.reflect.Array;

public class testArray {
    public static void main(String[] args) {
        int[] arr1 ={1,2,3,4};
        int[] arr2=null;
    Class<?>  c = arr1.getClass().getComponentType();
    arr2 =(int[]) Array.newInstance(c, 15);
    int len =Array.getLength(arr1);
    System.out.println(len);
    System.arraycopy(arr1, 0, arr2, 0, len);
    Class<?> c1 = arr2.getClass();
    if(!c1.isArray()){
        return;
    }
    System.out.println("新数组的长度:"+Array.getLength(arr2));
    for(int i=0;i<Array.getLength(arr2);i++){
        System.out.print(Array.get(arr2, i));
    }
    }
}

输出结果:

4

新数组的长度:15

123400000000000

  • 查看类加载器
//查看类加载器
        test01 t = new test01();
        System.out.println("类加载器:"+t.getClass().getClassLoader().getClass().getName());

输出结果:类加载器:sun.misc.Launcher$AppClassLoader

在java中有三种类类加载器。

1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。

2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类

3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。

如果想要完成动态代理,首先需要定义一个InvocationHandler接口的子类,已完成代理的具体操作。

package Reflect;
import java.lang.reflect.*;

//定义项目接口
interface Subject {
    public String say(String name, int age);
}

// 定义真实项目
class RealSubject implements Subject {
    @Override
    public String say(String name, int age) {
        return name + "  " + age;
    }
}

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;
    }
}

class hello {
    public static void main(String[] args) {
        MyInvocationHandler demo = new MyInvocationHandler();
        Subject sub = (Subject) demo.bind(new RealSubject());
        String info = sub.say("Rollen", 20);
        System.out.println(info);
    }
}

输出结果:Rollen 20

  • 反射用于工厂设计模式
package Reflect;

public class Apple implements fruit{

    @Override
    public void eat() {
        // TODO Auto-generated method stub
        System.out.println("apple");
    }

}
package Reflect;

public class Orange implements fruit {

    public void eat() {
        // TODO Auto-generated method stub
        System.out.println("orange");
    }

}
package Reflect;

public interface fruit {
    public void eat();
}
package Reflect;

public class Factory {
    public static fruit getInstance(String fruitName) throws InstantiationException, IllegalAccessException, ClassNotFoundException{
        fruit f =null;

            f= (fruit) Class.forName(fruitName).newInstance();

    return f;
    }
}
package Reflect;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class init {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    /*fruit f = Factory.getInstance("Reflect.Apple");
    f.eat();*///未用properties配置文件时
    try {
        Properties p = getData();
        fruit f =Factory.getInstance(p.getProperty("apple"));
        if(f!=null){
            f.eat();
        }

    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}
/**
 *
 * @return
 * @throws FileNotFoundException
 * @throws IOException
 */

public static Properties getData() throws FileNotFoundException, IOException{
    Properties p = new Properties();
    File f = new File("fruit.properties");
    if(f.exists()){
        p.load(new FileInputStream(f));
    }else{
        p.setProperty("apple","Reflect.Apple");
        p.setProperty("orange", "Reflect.Orange");
        p.store(new FileOutputStream(f), "FRUIT CLASS");
    }
    return p;

}
}
  • 反射与new的区别

1、反射是动态编译,new是静态编译,静态编译就是在编译的时候把你所有的模块都编译进exe里去。动态编译的时候那些模块都没有编译进去,这样启动程序(初始化)的时候这些模块不会被加载,而是在运行的时候,用到那个模块就调用哪个模块

2、new对象,无法调用该类里面私有的东西,反射反之,

时间: 2024-10-16 20:28:28

通过案例一步学习理解java反射机制的相关文章

封装jdbc让你轻松理解Java反射机制

1.目录结构 2.BasicDao.java static{ try { Class.forName("com.mysql.jdbc.Driver"); } catch (Exception e) { e.printStackTrace(); } } public Connection getConnection() throws SQLException{ String url = "jdbc:mysql://127.0.0.1:3306/dbparam?autoRecon

Java知识总结:Java反射机制(用实例理解)

概念理解: 反射是指一类应用,它们能够自描述和自控制.也就是说,这类应用通过采用某种机制来 实现对自己行为的描述( self-representation )和检测( examination) ,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. Java中的反射是一个强大的工具,他能够创建灵活的代码,这些 代码可以在运行时装配,无需在组件之间进行链接,发射允许在编写和执行时,使程序代码能够接入装载到 JVM 中的类的内部信息 .而不是源代码中选定的类协作的代码.这使发射

Java反射机制浅析图+应用实例

Java反射机制浅析图+应用实例 --转载请注明出处:coder-pig 本节引言: 其实很久之前就想归纳一下Java中的这个反射机制了,前些天看了慕课网一个讲反射机制的 视频教程觉得不错,又复习了一下,今天面试了一下午,回来就不想写代码了,就写写关于Java 反射的总结,写些简单的使用例子,最后找了2个Android中反射机制应用的例子,分别是 旧版本SDK利用AIDL + Java反射机制接听与挂断电话以及利用反射机制通过按钮关闭 对话框,后续如果用到会另外总结~ 本节正文: 1.反射的相关

Java反射学习:深入学习Java反射机制

一.Java反射的理解(反射是研究框架的基础之一) Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制. 二.逐步分析 参考:https://blog.csdn.net/u012585964/article/details/52011138 1.关于Class 1.Class是一个类,一个描述类的类(也就是描述类本身),封装了描述方法的Met

JAVA反射机制—学习总结

最近收到很多关于Java反射机制的问题留言,其实Java反射机制技术方面没有太多难点,或许是大家在学习过程中遗漏了细小知识点,导致一些问题无法彻底理解,现在我们简单的总结一下,加深印象. 什么是反射机制? "JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制."我们通过一些例子,更好理解反射机制.Class类 我们知道Java是一门面向对象

Java反射机制的学习

Java反射机制是Java语言被视为准动态语言的关键性质.Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调用其方法或修改其域(甚至是本身声明为private的域或方法). 也许你使用Java已经很长时间了,可是几乎不会用到Java反射机制.你会嗤之以鼻地告诉我,Java反射机制没啥用.或许在J2EE.J2SE等平台,Java反射机制没啥用(具体我也不了解,不多做评论),但是在Android应用开发中,该

Java反射机制学习

Java 反射是Java语言的一个很重要的特征,它使得Java具体了“动态性”. 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?答案是肯定的.这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射(Reflection)机制. Java 反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类. 在运行时构造任意一个类的对象. 在运行时判断任意一个类所具有的成员变量和方法. 在运行时调用任意一个对象的

[转载] Java反射机制的学习

本文转载自: http://www.blogjava.net/zh-weir/archive/2011/03/26/347063.html Java反射机制是Java语言被视为准动态语言的关键性质.Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调用其方法或修改其域(甚至是本身声明为private的域或方法). 也许你使用Java已经很长时间了,可是几乎不会用到Java反射机制.你会嗤之以鼻地告诉我,Ja

Java学习之:反射机制

一.反射机制应用场景 知道在哪里用的情况很重要,任何东西的产生都有他的来由,知道了场景才知道为什么要发明这个东西. 一般在开发针对java语言相关的开发工具和框架时使用,比如根据某个类的函数名字,然后执行函数,实现类的动态调用! 而且这么看,所有面向对象的语言可能都会用到这个机制,西草原生并不支持这种机制,但是可以手动实现,详情请见好基友的文章,http://blog.csdn.net/k346k346/article/details/51698184 二.反射机制 言归正传,来具体说说什么是反