`
chenzehe
  • 浏览: 538223 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Java 反射

阅读更多

1、 什么是反射

反射指程序在运行期间可以访问、检测、修改其自身的状态和行为的一种能力。 Reflection 是  Java  程序开发语言的特征之一,它允许运行中的  Java  程序对自身进行检查,或者说 自审 ,并能直接操作程序的内部属性和方法 允许程序于执行期 Reflection APIs  取得任何已知名称之  class  的內部信息,包括  package type parameters superclass implemented interfaces inner classes, outer class, fields constructors methods modifiers ,並可于执行期生成 instances 、变更  fields  內容或唤起  methods

 

 

2、 Object类的 getClass() 方法

Class <?>   getClass ()  返回此 Object  的运行时类 ,所有子类都可以继承此方法,如:

创建类Person.java

package com.chenzehe.reflection;

public class Person {

}

测试类:

package com.chenzehe.reflection;

public class PersonClassDemo {

public static void main(String[] arg) {

     Person person = new Person();

System.out.println(person.getClass());

        System.out.println(person.getClass().getName());

    }

}

第一行输出:class com.chenzehe.reflection.Person getClass() 返回类型为 class

第二行输出Person 类的全称: com.chenzehe.reflection.Person

 

 

3、 Class

public final class  Class<T>   extends  Object  i mplements  Serializable GenericDeclaration Type AnnotatedElement

Class 类的实例表示正在运行的  Java  应用程序中的类和接口。 java反射机制中, Class 类是一个操作源头,所有操作都从此类展开,有三种方式可以实例化此类:

 

3.1 Object 类中的 Class <?>   getClass () 方法

测试类:

package com.chenzehe.reflection;

public class PersonClassDemo {

     public static void main(String[] arg) {

         Person person = new Person();

         Class<?> p = person.getClass();

         System.out.println(p.getName());

     }

}

输出:com.chenzehe.reflection.Person

 

 

3.2 通过 类 .class  的形式,如 Person.class

package com.chenzehe.reflection;

public class PersonClassDemo {

     public static void main(String[] arg) {

         Class<?> p = Person.class;

         System.out.println(p.getName());

     }

}

输出:com.chenzehe.reflection.Person

 

 

3.3 通过 Class 类的表态方法,此种方式常用

static  Class <?>   forName ( String  name, boolean initialize,  ClassLoader  loader)

name为类的全称

package com.chenzehe.reflection;

public class PersonClassDemo {

     public static void main(String[] arg) {

        try {

             Class<?> p = Class.forName("com.chenzehe.reflection.Person");

             System.out.println(p.getName());

        }

        catch (ClassNotFoundException e) {

            e.printStackTrace();

        }

    }

}

输出:com.chenzehe.reflection.Person

 

 

4、 通过Class 类实例化对象

 

4.1  无参构造函数

 

正常情况下实例化对象通过new 关键字实现,使用 Class 方式有下面两种步骤:

4.1.1  通过 Class.forName() 方法取得类型

4.1.2  通过类型的 newInstance() 方法实例化对象

  T   newInstance ()  创建此 Class  对象所表示的类的一个新实例

package com.chenzehe.reflection;

public class PersonClassDemo {

     public static void main(String[] arg) throws Exception {

         Class<?> p = Class.forName("com.chenzehe.reflection.Person");

         System.out.println(p);

         System.out.println(p.newInstance());

    }

}

第一行输出Class 的类型: class com.chenzehe.reflection.Person

第二行输出该类型的一个实例地址:com.chenzehe.reflection.Person@c17164

 

4.2  有参构造函数

此种方式不方便,推荐使用无参构造方法。

重构Person 类,只加入有参构造函数,如下:

package com.chenzehe.reflection;

public class Person {

     private String name;

     private String password;

     public Person(String name, String password) {

         this.name = name;

         this.password = password;

     }

 public String getName() {

         return this.name;

     }

     public void setName(String name) {

         this.name = name;

     }

     public String getPassword() {

         return this.password;

     }

     public void setPassword(String password) {

         this.password = password;

     }

}

些时再运行上面的 newInstance ()方法,就会出现 java.lang.InstantiationException 异常。

使用Class 的静态方法:

p ublic   Constructor < T > []   getConstructor s ( Class <?>... parameterTypes)   throws  NoSuchMethodException SecurityException

返回所有的构造方法,返回类型为数组,第一个元素为参数最多的构造方法,依此反推。然后再调用 Constructor的静态方法: T   newInstance ( Object ... initargs) 来实例化对象,如:

package com.chenzehe.reflection;

import java.lang.reflect.Constructor;

public class PersonClassDemo {

     public static void main(String[] arg) throws Exception {

         Class<?> p = Class.forName("com.chenzehe.reflection.Person");

         Constructor<?> c[] = p.getConstructors();

         Person person = (Person) c[0].newInstance("chenzehe", "chenzehe");

         System.out.println(person.getName());

       }

}

 

5、通过 Class 取得完整结构

 

5.1   Class <? super  T >   getSuperclass () 

取得 表示此 Class  所表示的实体(类、接口、基本类型或  void )的超类的  Class

5.2   Class <?>[]   getInterfaces () 

取得 此对象所表示的类或接口实现的接口

5.3  Method   getMethod ( String  name,  Class <?>... parameterTypes) 

取得所有方法

Method  类中的方法:int  getModifiers () 以整数形式返回此 Method  对象所表示方法的  Java  语言修饰符 ,如果想转换成 public private 等关键字则使用 java.lang.reflect.Modifier 类的 static  String   toString (int mod)  方法。

String   getName () 以 String  形式返回此  Method  对象表示的方法名称

5.4     Field []   getFields () 

取得一个类的全部属性

 

 

6、 通过反射调用类中的方法

 

正常情况下是通过 对象. 方法 ()  的方式来调用对象中的方法,使用反射调用类中的方法时按如下步骤:

 

6.1  先通过 Class 对象的下面方法取得 Method 对象

Method   getMethod ( String  name,  Class <?>... parameterTypes)  返回一个 Method  对象,它反映此  Class  对象所表示的类或接口的指定公共成员方法。 name为方法名称,后面可变参数表示方法参数。

 

6.2  调用 Method 对象的下面方法执行该方法

Object   invoke ( Object  obj,  Object ... args)  对带有指定参数的指定对象调用由此 Method  对象表示的底层方法。 obj参数为 Class 对象的一个实例。

调用无参没有返回值的方法:

在上面Person 类中添加 sayHelloWorld() 方法:

public void sayHelloWorld() {

     System.out.println("Hello World!");

}

调用如下:

package com.chenzehe.reflection;

import java.lang.reflect.Method;

public class PersonClassDemo {

     public static void main(String[] arg) throws Exception {

         Class<?> p = Class.forName("com.chenzehe.reflection.Person");

         Method m = p.getMethod("sayHelloWorld");

         m.invoke(p.newInstance());

     }

}

输出:Hello World!

调用无参有返回值的方法:

Person 类中添加方法:

public String getHelloWorld() {

     return "Hello World!";

}

调用如下:

package com.chenzehe.reflection;

import java.lang.reflect.Method;

 

public class PersonClassDemo {

     public static void main(String[] arg) throws Exception {

          Class<?> p = Class.forName("com.chenzehe.reflection.Person");

         Method m = p.getMethod("getHelloWorld");

         String result = (String) m.invoke(p.newInstance());

         System.out.println(result);

     }

}

输出:Hello World!

调用有参有返回值的函数:

Person 类中添加方法:

public String say(String name, String context) {

     return name + ":" + context;

}

调用:

package com.chenzehe.reflection;

import java.lang.reflect.Method;

public class PersonClassDemo {

     public static void main(String[] arg) throws Exception {

         Class<?> p = Class.forName("com.chenzehe.reflection.Person");

         Method m = p.getMethod("say", String.class, String.class);

         String result = (String) m.invoke(p.newInstance(), "chenzehe", "Hello World!");

          System.out.println(result);

     }

}

输出:chenzehe:Hello World!

 

调用set get 方法,也可以像上面那样把 set get 方法名传进去直接调用,也可以像下面这样调用:

package com.chenzehe.reflection;

import java.lang.reflect.Method;

public class PersonClassDemo {

     public static void main(String[] arg) throws Exception {

         Class<?> c = Class.forName("com.chenzehe.reflection.Person");

         Object o = c.newInstance();

         set("name", "chenzehe", o, String.class);

         System.out.println(get("name", o));

     }

     // 调用 set 方法         public static void set(String name, Object value, Object obj, Class<?> type) throws Exception {

         Method m = obj.getClass().getMethod("set" + upFirstString(name), type);

         m.invoke(obj, value);

    }

    // 调用 get 方法

    public static Object get(String name, Object obj) throws Exception {

    Method m = obj.getClass().getMethod("get" + upFirstString(name));

        return m.invoke(obj);

    }

    // 把属性的第一个字母大写

    public static String upFirstString(String name) {

        StringBuffer buf = new StringBuffer();

        buf.append(name.substring(0, 1).toUpperCase()).append(name.substring(1));

        return buf.toString();

    }

}

 

 

7、 通过反射操作属性

package com.chenzehe.reflection;

import java.lang.reflect.Field;

public class PersonClassDemo {

     public static void main(String[] arg) throws Exception {

        Class<?> c = Class.forName("com.chenzehe.reflection.Person");

        Object o = c.newInstance();

        Field field = c.getDeclaredField("name");

        field.setAccessible(true);

        field.set(o, "chenzehe");

        System.out.println(field.get(o));

    }

}

输出:chenzehe

一般不直接操作属性,而是通过set get 方法操作。

 

 

 

用反射解析jar文件并执行里面Java代码

 

 

动态代理反射

  Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:

    (1). Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method, Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,这个抽象方法在代理类中动态实现。 

    (2).Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject,其中主要包含以下内容: 
      Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。 

      Static Class getProxyClass (ClassLoader loader, Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。 

      Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。

 

  所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些 interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。

 

         如Spring AOP的实现使用了动态代理

 

 

 

分享到:
评论

相关推荐

    java反射 java反射 java反射java反射

    Java反射是Java编程语言中的一个重要特性,它允许程序在运行时动态地获取类的信息并操作类的对象。在Java中,反射机制提供了强大的能力,包括在运行时检查类的结构、创建对象实例、调用方法以及访问和修改字段值。...

    JAVA反射机制的入门代码

    Java反射机制是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。这个特性使得Java具有了高度的灵活性和动态性,尤其是在处理元数据、创建对象、调用私有方法...

    java反射,获取所有属性、方法以及List集合类

    Java反射是Java编程语言中的一个强大工具,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射主要用于在运行时分析类和对象,包括访问私有成员、调用私有方法、创建对象、获取类...

    JAVA 反射机制应用

    Java反射机制是Java语言提供的一种强大功能,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制的核心类是java.lang.Class,它代表了运行时的类信息。通过Class对象,我们...

    java 反射得到某个方法

    在本文中,我们将深入探讨如何使用Java反射来获取并执行某个特定的方法。 首先,我们需要了解Java反射的基本概念。`java.lang.Class`类是反射的核心,它代表了Java中的每一个类。我们可以通过以下方式获取到一个...

    Java反射性能测试分析

    ### Java反射性能测试分析 #### 引言 Java反射机制是Java编程语言中一个强大的特性,它允许程序在运行时动态地访问、检测和修改类、接口、字段和方法等对象。然而,反射操作通常会引入额外的开销,这在性能敏感的...

    Java反射机制总结

    ### Java反射机制总结 #### 反射的概念与起源 反射的概念最早由Smith于1982年提出,指的是程序能够访问、检测并修改其自身状态或行为的能力。这一概念的提出迅速引起了计算机科学领域的广泛关注,并在之后的研究中...

    Java反射经典实例

    Java反射是Java编程语言中的一个强大特性,它允许运行时的程序访问并操作类、接口、字段和方法等信息,即使这些信息在编译时并未明确知晓。在Java中,反射通常通过`java.lang.Class`类和相关的API来实现。本实例将...

    java反射-英文版反射规范

    ### Java反射机制详解 #### 一、概述 Java反射机制是一种强大的编程技术,它允许运行时检查类的信息并操作对象的内部结构。本篇将基于Sun公司的官方文档《Java™ Core Reflection API and Specification》(1997年...

    反射实例-JAVA反射机制

    ### 反射实例—JAVA反射机制 #### 一、反射概念及原理 反射在计算机科学领域,特别是程序设计中,是指程序有能力访问、检测和修改其自身的结构和行为。这一概念最早由Smith于1982年提出,并迅速应用于各种编程语言...

    java反射.pdf

    ### Java反射机制详解 #### 一、什么是Java反射? Java反射是Java编程语言的一个特性,它允许运行时检查和操作程序结构(类、字段、方法等)。反射的主要用途包括但不限于:动态实例化对象、访问私有成员、调用...

    java 反射 调用私有方法(有参数私有方法)获取私有属性值

    Java反射是Java语言提供的一种强大的动态类型特性,它允许程序在运行时检查类、接口、字段和方法的信息,并且能够动态地创建对象和调用方法。这个能力使得开发者可以突破静态类型的束缚,实现一些在编译时期无法完成...

    java反射源代码

    Java反射是Java编程语言中的一个强大特性,它允许在运行时检查类、接口、字段和方法的信息,并且能够在运行时动态地创建对象和调用方法。这个特性使得Java具有高度的灵活性,尤其在处理框架、插件系统以及元数据驱动...

    java 反射机制例子

    ### Java反射机制详解 #### 一、反射的基本概念与历史背景 反射的概念最早由Smith在1982年提出,其核心思想是程序有能力访问、检测甚至修改自身的状态和行为。这种能力一经提出,迅速成为了计算机科学领域的研究...

    java 反射 报错 no such method exception

    ### Java反射机制与NoSuchMethodException详解 在Java编程中,反射是一种强大的机制,允许程序在运行时检查和修改自身结构和行为。然而,当开发者尝试使用反射调用一个不存在的方法时,便会遇到`java.lang....

    java反射获取所有属性,获取所有get方法,包括子类父类

    Java反射是Java编程语言中的一个强大工具,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射主要用于在运行时分析类和对象,包括访问私有成员、调用私有方法、创建动态代理等。...

    利用java反射将json字符串转成对象.zip

    Java反射是Java编程语言中的一个强大工具,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在给定的“利用java反射将json字符串转成对象”的主题中,我们将深入探讨如何借助反射机制将JSON...

    Java反射机制Demo

    ### Java反射机制详解 #### 一、什么是Java反射机制? Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的...

    北大青鸟java反射机制

    Java反射机制是Java编程语言中的一个强大工具,它允许程序在运行时检查并操作类、接口、字段和方法等对象。在"北大青鸟java反射机制"的学习资料中,我们将会深入探讨这一核心特性。 首先,我们要理解反射的核心概念...

    java反射

    ### Java反射机制详解 #### 一、引言 在Java编程语言中,反射(Reflection)是一种强大的工具,它允许程序在运行时访问类的信息,并能够动态地创建对象、调用方法以及获取字段值等。这种能力对于框架设计、代码...

Global site tag (gtag.js) - Google Analytics