java 反射浅析

最近看rpc框架,中间用到了反射,以前也早就听说过反射,用处大大的广。

反射的作用

Java的反射机制、能够在java运行时根据类的路径去获取与路径对应的Class对象。在根据这个类对象去获取类的成员变量、方法、构造这些东西、哪怕他们是私有的。获取到这些东西来做什么?你可以用他们来判断、也可以调用他们去完成某些功能。

反射机制就是专门帮我们做那些重复的有规则的事情。

反射的常用用法:

  • 利用打开office软件的demo,不用修改main程序,根据输入动态地调用对应的office,方便扩展。
package office;

public class Office {
    public static void main(String[] args) {
        Class c = null;
        try {
            c = Class.forName(args[0]);
        } catch (ClassNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        OfficeAble office = null;

        try {
            office =  (OfficeAble) c.newInstance();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        office.start();
    }

}
package office;

public interface OfficeAble {
    public void start();
}
package office;

public class Excel implements OfficeAble{

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

}
package office;

public class Word implements OfficeAble{

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

    }

}
  • 下面是反射的常用用法展示:包括获取类类型的几种方法、利用类类型生成对象、获取方法名字、变量、构造函数、函数返回值、函数调用、以及一个表现反射是发生在运行期的。
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

//打印类中的相关信息,包括方法名、成员变量、构造函数
public class ReflectTest3 {

    //获取类类型的几种方法
    public void getClassType() {

        // one
        Class c1 = A.class;
        System.out.println(c1);
        //second
        A a = new A();
        Class c2 = a.getClass();
        System.out.println(c2);
        System.out.println(c1 == c2);
        //third
        Class c3 = null;
        try {
            c3 = Class.forName("A");
            System.out.println(c3);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        //利用类类型去生成对象
        try {
            A test = (A) c1.newInstance();
            test.print();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    //打印方法信息
    public void printMethodMessage(Object object) {
        //获取类类型
        Class test = object.getClass();
        //获取方法名数组,获取返回值、方法名、参数类型
        Method[] methods = test.getMethods();
        for(int i=0; i<methods.length; ++i) {
            Class returnType = methods[i].getReturnType();
            System.out.print(returnType.getName()+ "");  //返回值
            System.out.print(methods[i].getName()+ "(");   //方法名
            Class[] paramTypes = methods[i].getParameterTypes();
            for(Class class1:paramTypes) {
                System.out.print(class1.getName());
            }
            System.out.println(")");
        }

    }

    //获取类的public的成员变量
    public void printFieldMessage(Object object) {
        Class c = object.getClass();
        Field[] fields = c.getDeclaredFields();
        for(Field field: fields) {
            Class fieldType = field.getType();
            String typeName = fieldType.getName();  //获取类型名
            String fieldName = field.getName();  //获取变量名
            System.out.println(typeName + " " + fieldName);
        }
    }

    //获取构造函数的信息
    public  void printConMessage(Object object) {
        Class c = object.getClass();
        //构造函数也是对象
        Constructor[] constructors = c.getDeclaredConstructors();
        for(Constructor cs: constructors) {
            System.out.print(cs.getName()+"(");  //获取构造函数名字
            Class[] paramTypes = cs.getParameterTypes();
            for(Class paramType:paramTypes) {
                System.out.print(paramType.getName()+ " ");
            }
            System.out.println(")");
        }
    }

    //方法反射
    public  void methodReflect() {
        //获取类类型
        A a = new A();
        Class c = a.getClass();

        //获取方法对象
        try {
            Method m1 = c.getMethod("print");
            m1.invoke(a);

            Method m2 = c.getMethod("print", int.class, int.class);
            m2.invoke(a, 1, 2);

            Method m3 = c.getMethod("print", String.class, String.class);
            m3.invoke(a, "hello", "world");

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

    //反射是在运行期的,绕过了编译器
    //通过arraylist添加不同类型的数据,来看看这个特性
    public void runtimeTest() {
        ArrayList<String> test = new ArrayList<String>();
        test.add("hello");
        //test.add(20);    //编译器报错
        Class c = test.getClass();
        Method m;
        try {
            m = c.getMethod("add", Object.class);
            m.invoke(test, 20);
            System.out.println(test.size());   //通过反射,已经将20添加到了ArrayList<String>中,绕过了编译器的语法检查
            System.out.println(test);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    //test method
    public static void main(String[] args) {
        ReflectTest3 test  = new ReflectTest3();
        System.out.println("-------------------分割线--获取类类型的几种方法-------------------");
        test.getClassType();

        System.out.println("-------------------分割线--打印方法信息-------------------");
        String s = "hello";
        test.printMethodMessage(s);   

        System.out.println("-------------------分割线--打印变量名信息-----------------");
        test.printFieldMessage(s);  

        System.out.println("-------------------分割线--打印构造函数信息--------------");
        test.printConMessage(s);   

        System.out.println("-------------------分割线--使用方法反射-----------------");
        test.methodReflect();

        System.out.println("-------------------分割线--反射是在运行期的-----------------");
        test.runtimeTest();
    }

}

class A {
    public void print() {
        System.out.println("hello,world");
    }

    public void print(int a, int b) {
        System.out.println(a+b);
    }

    public void print(String a, String b) {
        System.out.println(a.toUpperCase()+","+b.toLowerCase());
    }
}

运行结果:

-------------------分割线--获取类类型的几种方法-------------------
class A
class A
true
class A
hello,world
-------------------分割线--打印方法信息-------------------
booleanequals(java.lang.Object)
java.lang.StringtoString()
inthashCode()
intcompareTo(java.lang.Object)
intcompareTo(java.lang.String)
intindexOf(java.lang.Stringint)
intindexOf(int)
intindexOf(intint)
intindexOf(java.lang.String)
java.lang.StringvalueOf(float)
java.lang.StringvalueOf(double)
java.lang.StringvalueOf(boolean)
java.lang.StringvalueOf([Cintint)
java.lang.StringvalueOf([C)
java.lang.StringvalueOf(java.lang.Object)
java.lang.StringvalueOf(char)
java.lang.StringvalueOf(int)
java.lang.StringvalueOf(long)
charcharAt(int)
intcodePointAt(int)
intcodePointBefore(int)
intcodePointCount(intint)
intcompareToIgnoreCase(java.lang.String)
java.lang.Stringconcat(java.lang.String)
booleancontains(java.lang.CharSequence)
booleancontentEquals(java.lang.StringBuffer)
booleancontentEquals(java.lang.CharSequence)
java.lang.StringcopyValueOf([Cintint)
java.lang.StringcopyValueOf([C)
booleanendsWith(java.lang.String)
booleanequalsIgnoreCase(java.lang.String)
java.lang.Stringformat(java.util.Localejava.lang.String[Ljava.lang.Object;)
java.lang.Stringformat(java.lang.String[Ljava.lang.Object;)
[BgetBytes()
[BgetBytes(java.lang.String)
voidgetBytes(intint[Bint)
[BgetBytes(java.nio.charset.Charset)
voidgetChars(intint[Cint)
java.lang.Stringintern()
booleanisEmpty()
intlastIndexOf(int)
intlastIndexOf(intint)
intlastIndexOf(java.lang.Stringint)
intlastIndexOf(java.lang.String)
intlength()
booleanmatches(java.lang.String)
intoffsetByCodePoints(intint)
booleanregionMatches(intjava.lang.Stringintint)
booleanregionMatches(booleanintjava.lang.Stringintint)
java.lang.Stringreplace(charchar)
java.lang.Stringreplace(java.lang.CharSequencejava.lang.CharSequence)
java.lang.StringreplaceAll(java.lang.Stringjava.lang.String)
java.lang.StringreplaceFirst(java.lang.Stringjava.lang.String)
[Ljava.lang.String;split(java.lang.String)
[Ljava.lang.String;split(java.lang.Stringint)
booleanstartsWith(java.lang.String)
booleanstartsWith(java.lang.Stringint)
java.lang.CharSequencesubSequence(intint)
java.lang.Stringsubstring(intint)
java.lang.Stringsubstring(int)
[CtoCharArray()
java.lang.StringtoLowerCase()
java.lang.StringtoLowerCase(java.util.Locale)
java.lang.StringtoUpperCase(java.util.Locale)
java.lang.StringtoUpperCase()
java.lang.Stringtrim()
voidwait(longint)
voidwait(long)
voidwait()
java.lang.ClassgetClass()
voidnotify()
voidnotifyAll()
-------------------分割线--打印变量名信息-----------------
[C value
int hash
long serialVersionUID
[Ljava.io.ObjectStreamField; serialPersistentFields
java.util.Comparator CASE_INSENSITIVE_ORDER
int HASHING_SEED
int hash32
-------------------分割线--打印构造函数信息--------------
java.lang.String([B )
java.lang.String([B int int )
java.lang.String([B java.nio.charset.Charset )
java.lang.String([B java.lang.String )
java.lang.String([B int int java.nio.charset.Charset )
java.lang.String(int int [C )
java.lang.String([C boolean )
java.lang.String(java.lang.StringBuilder )
java.lang.String(java.lang.StringBuffer )
java.lang.String([I int int )
java.lang.String([C int int )
java.lang.String([C )
java.lang.String(java.lang.String )
java.lang.String()
java.lang.String([B int int java.lang.String )
java.lang.String([B int )
java.lang.String([B int int int )
-------------------分割线--使用方法反射-----------------
hello,world
3
HELLO,world
-------------------分割线--反射是在运行期的-----------------
2
[hello, 20]

反射的应用

工厂方法、代理+代理=动态代理(应用在spring的AOP上)、ibatis等

下面是我用maven+java反射+注解+jdbc写的一个简单的orm,代码放在github:https://github.com/zy416548283/JDBCSimpleORM

反射优缺点

优点:按名称动态检索信息,让运行中的程序操作这些信息,无需提前硬编码目标类。

缺点:性能问题.

反射原理

待分析

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-14 19:31:16

java 反射浅析的相关文章

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

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

Java反射机制浅析

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. "程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言".从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言.但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载.探知.使用

浅析Java反射机制

一.反射的理解 反射类似于我们平时见到的平面镜的反射:被反射的目标(任意一个已知名称的类),反射出来的"镜像"(我们的类对象<Java中任意一个类都对应有一个类对象>),通过这个"镜像",类对象,我们就可以在运行时获取任意一个已知名称的类对应的信息. 二.Java反射机制提供的功能 Java反射机制主要提供了以下功能:在运行时判断任意一个独享所属的类:在运行时构造任意一个类的对象:在运行时判断任意一个类所具有的成员变量和方法:在运行时调用任意一个对象的方

Java 反射机制浅析

转:http://www.cnblogs.com/gulvzhe/archive/2012/01/27/2330001.html ———————————————————————————————————————————————— Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制.反射的概念是由Smith在1982年首次提出的,主要是指程序可以

Java annotation浅析

自定义annotation @Documented@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})public @interface TestAnnotation {    //default关键字是用来设置注解的默认值,可有可没有    String value() default("Hello,I am a field");    S

Java反射机制大神必学系列之 ,高级与低级的差别在哪里?

Java反射机制大神必学系列之 ,高级与低级的差别在哪里?java学习爱好者 2019-05-20 19:08前言今天介绍下Java的反射机制,以前我们获取一个类的实例都是使用new一个实例出来.那样太low了,今天跟我一起来学习学习一种更加高大上的方式来实现. 正文Java反射机制定义 Java反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制.

Java反射

1. 介绍 反射是一种能够在程序运行时动态访问.修改某个类中任意属性和方法的机制. 具体:对于任意一个类,都能够知道这个类的所有属性和方法对于任意一个对象,都能够调用它的任意一个方法和属性 在运行时,当加载完类之后,JVM在堆内存中会自动产生一个Class类型的对象,这个对象包含了完整的类的结构信息 这个Class对象就像一面镜子,透过这个镜子看到类的结构 那么,如何得到这个Class对象呢?以下可否 Class c = new Class(); 答案是不行的,因为Class的构造函数定义为私有

Java 反射详解

反射反射,程序员的快乐,今天你快乐了吗?如果你不快乐,没关系,接下来让你快乐起来! 一.什么是反射? 通过百度百科我们可以知道,Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:并且能改变它的属性.而这也是Java被视为动态(或准动态,为啥要说是准动态,因为一般而言的动态语言定义是程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言.从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C

java反射机制(一)—— 利用反射机制实例化对象

一.Java有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载.探知.使用编译期间完全未知的classes.换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体.或对其fields设值.或唤起其methods.(度娘文库是这么说的) 二.这篇文章主要介绍一下通过反射机制去实例化一个类的对象,然后调用其方法.本文主要介绍两种方式,第一种就是通过构造函数来实例化,第二种就是通过Cl