java反射简解

1、首先一个问题,什么是类,类是不是对象?

我们总是说我们new一个对象出来

那么我们还没有new的时候,建造的那个java类是不是对象呢?

它是java.lang.Class的对象

对于反射我们首先要知道的就是什么是Class类

java.lang.Class到底是什么,有啥用。

首先我们要得到Class,我们有三种可以得到的方法,代码如下,c1,c2,c3就是我们需要的Class

//任何一个类都有一个隐含的成员变量叫做calss
Class c1 = Man.class;

//通过对象的getClass方法获取class
Class c2 = man1.getClass();

//c1和c2表示了Man的类类型,也就是class type

Class c3 = null;
c3 = Class.forName("com.clazz.test.Man");

需要知道的是类的类类型是一样的,都指的是一个,所以c1,c2,c3都是一样的。都是相等的。

那我们现在已经拿到了Class,可以用它来干嘛呢?

我们可以通过类的类类型直接创建一个对象,也就是说,没有new了。

需要注意的是下面的代码中newInstance方法会调用类的无参构造方法

//通过类的类类型创建对象。
Man man2 = (Man) c1.newInstance();

下面是所有的测试代码

package com.clazz.test;

/**
 * Class类的描述测试
 * @author XX
 *
 */
public class ClazzDemo1 {

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException
    {
        //Man是java.lang.Class的对象
        //任何一个类都是class类的实例对象

        Man man1 = new Man();
        //man1是Man类的实例对象

        //任何一个类都有一个隐含的成员变量叫做calss
        Class c1 = Man.class;

        //通过对象的getClass方法获取class
        Class c2 = man1.getClass();

        //c1和c2表示了Man的类类型,也就是class type

        Class c3 = null;
        c3 = Class.forName("com.clazz.test.Man");

        //通过类的类类型创建对象。
        Man man2 = (Man) c1.newInstance();
    }
}

class Man{
    public Man(){
        System.out.println("创建了这个类");
    }
}

2、静态加载类和动态加载类

new创建对象是静态加载,在编译时刻就需要加载所有可能使用到的类。

通过动态加载类,可以在运行时刻加载使用到的类

也就是我们的c3使用的方法

package com.clazz.test;

public class DynamicLoadClass {

    public static void main(String args[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException
    {
        //静态加载类,直接new出对象,调用方法,一般都是使用这个,但是一旦没有Student类,编译就会报错
        //而且如果需要使用老师对象那么代码需要重新写过很多,要把new对象重新写过,
        Student s1 = new Student();
        s1.speck();

        //通过动态加载类,编译时刻,无论学生还是老师类存不存在,都可以编译通过,只有当运行时刻才进行加载
        //好处是如果你需要新增一个类,直接实现IPeople接口,只要forName的名字正确即可,而且这个名字可以
        //作为一个参数传进来然后进行修改
        Class c1 = Class.forName("com.clazz.test.Student");
        IPeople p1 = (IPeople) c1.newInstance();
        p1.speck();
    }
}
package com.clazz.test;

public class Student implements IPeople{

    public void speck()
    {
        System.out.println("我是学生");
    }
}
package com.clazz.test;

public interface IPeople {

    public void speck();
}

3通过反射拿到一个类的所有的信息

下面这个就是反射最基本的用法,也是反射最神奇的地方

package com.clazz.util;

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

import com.clazz.test.Student;

/**
 * calss类的测试工具类
 * @author XX
 *
 */
public class ClazzUtil {

    public static void main(String args[])
    {
        //通过反射能拿到类的所有方法信息
        printAll(new Student());
    }

    /**
     * 获取这个对象的信息并打印出来
     */
    public static void printAll(Object object)
    {
        Class c = object.getClass();

        //打印该类的名字
        System.out.println("类的名字" + c.getName());

        //打印该类的所有方法(包含从父类继承来的)(不包含私有的方法)
        Method[] ms = c.getMethods();
        for (Method method : ms) {
            System.out.println("方法:" + method.getName() + "          方法的返回值:" + method.getReturnType().getName());

            //获取方法的参数
            Class<?>[] par = method.getParameterTypes();
            for (Class<?> class1 : par) {
                System.out.println("方法的入参:" + class1.getName());
            }
        }

        //打印该类的方法(不包含从父类继承来的)包含私有方法
        Method[] ms2 = c.getDeclaredMethods();
        for (Method method : ms2) {
            System.out.println("方法1:" + method.getName() + "          方法的返回值:" + method.getReturnType().getName());
        }

        //获取成员变量(不包含私有变量)
        Field[] fs = c.getFields();
        for (Field field : fs) {
            System.out.println("成员变量: " + field.getName());
        }

        //获取成员变量(包含私有变量)
        Field[] fs1 = c.getDeclaredFields();
        for (Field field : fs1) {
            System.out.println("成员变量: " + field.getName());
        }

        //获取构造方法
        Constructor[] con = c.getDeclaredConstructors();
        for (Constructor constructor : con) {
            System.out.println("构造方法:" + constructor.getName());
        }
    }
}
package com.clazz.test;

public class Student implements IPeople{

    private int a1;
    public int a12;

    public void speck()
    {
        System.out.println("我是学生");
    }

    private void speck2()
    {
        System.out.println("我是学生");
    }
}

4通过反射调用类的方法

这个是反射的应用,通过反射调用一个类的方法

package com.clazz.test;

import java.lang.reflect.Method;

/**
 * @author XX
 *
 */
public class ReflectMethod {

    public static void main(String args[]) throws Exception
    {
        A a = new A();

        Class c = a.getClass();

        Method m = c.getMethod("add", int.class,int.class);

        System.out.println(m.invoke(a, 1,2));
    }
}

class A{
    public int add(int a,int b)
    {
        return a+b;
    }
    private int minus(int a,int b)
    {
        return a-b;
    }
}

5利用反射解释ArrayList的泛型

package com.clazz.test;

import java.lang.reflect.Method;
import java.util.ArrayList;

public class ArrayListRflect {

    public static void main(String args[]) throws Exception
    {
        /**
         * 下面的代码用于证明,在ArrayList中,泛型只在编译之前有效,编译之后泛型对于list的限制
         * 是无效的。利用反射就能绕过编译这个阶段在ArrayList添加本不属于该泛型的值
         */
        ArrayList<String> list = new ArrayList<String>();

        list.add("哈哈");
        //list.add(1);如果原来这么写,编译会报错的

        //那么怎么在list放个int的1呢?

        //获取list的类类型
        Class c = list.getClass();
        //通过类类型拿到方法
        Method m = c.getMethod("add",Object.class);
        //通过反射调用方法
        m.invoke(list, 1);

        System.out.println(list);
        //结果为:[哈哈, 1]

        //所以证明了上面的观点,也同时很好的证明了反射多神奇
    }
}
时间: 2024-10-12 15:17:40

java反射简解的相关文章

java 反射 详解

本文来自:blog.csdn.net/ljphhj JAVA反射机制:   通俗地说,反射机制就是可以把一个类,类的成员(函数,属性),当成一个对象来操作,希望读者能理解,也就是说,类,类的成员,我们在运行的时候还可以动态地去操作他们. 理论的东东太多也没用,下面我们看看实践 Demo - Demo: package cn.lee.demo; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import

Java反射详解

Java反射详解 分类:java, 基础日期:2012-07-20作者:ticmy 19 反射,是Java中非常重要的一个功能,如果没有反射,可以说很多框架都难以实现. 什么是反射?说白了就是可以通过Java代码获取装载到方法区的类信息的手段. 当装载一个类时,会在方法区产生一个数据结构,该结构中包含着装载的类的相关信息.字节码可以看成是数据流,那么方法区的这种数据结构可以说是字节码数据流的结构化表现.装载的最终产物就是java.lang.Class类的一个对象,它是Java程序与方法区内部数据

java反射详解 (转至 http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html)

本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案例1]通过一个对象获得完整的包名和类名 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package Reflect; /**  * 通过一个对象获得完整的包名和类名  * */ class Demo{     //other codes... } class hello{     pu

Java 反射详解 转载

java 反射 定义 功能 示例 概要: Java反射机制详解 | |目录 1反射机制是什么 2反射机制能做什么 3反射机制的相关API ·通过一个对象获得完整的包名和类名 ·实例化Class类对象 ·获取一个对象的父类与实现的接口 ·获取某个类中的全部构造函数 - 详见下例 ·通过反射机制实例化一个类的对象 ·获取某个类的全部属性 ·获取某个类的全部方法 ·通过反射机制调用某个类的方法 ·通过反射机制操作某个类的属性 ·反射机制的动态代理 4反射机制的应用实例 ·在泛型为Integer的Arr

Java 反射详解

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

java反射详解及说明

首先写一个Person类: 1 package lltse.base.reflectdemo; 2 3 public class Person 4 { 5 6 private String name; 7 8 public String getName() { 9 return name; 10 } 11 12 13 14 public void setName(String name) { 15 this.name = name; 16 } 17 18 19 20 public int get

转 java反射详解

本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案例1]通过一个对象获得完整的包名和类名 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package Reflect; /**  * 通过一个对象获得完整的包名和类名  * */ class Demo{     //other codes... } class hello{     publ

java反射详解(转)

本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案例1]通过一个对象获得完整的包名和类名 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package Reflect; /**  * 通过一个对象获得完整的包名和类名  * */ class Demo{     //other codes... } class hello{     publ

【转】java反射详解

转自:http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html 本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案例1]通过一个对象获得完整的包名和类名 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package Reflect; /**  * 通过一个对象获得完整