反射_反射机制 - CSDN
反射 订阅
反射是一种计算机处理方式。有程序可以访问、检测和修改它本身状态或行为的这种能力。能提供封装程序集、类型的对象。(程序集包含模块,而模块包含类型,类型又包含成员。) 展开全文
反射是一种计算机处理方式。有程序可以访问、检测和修改它本身状态或行为的这种能力。能提供封装程序集、类型的对象。(程序集包含模块,而模块包含类型,类型又包含成员。)
信息
性    质
计算机术语
应用领域
软件工程
外文名
reflection
中文名
反射
基本释义
提供封装程序集、类型的对象
反射用途
您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。1.使用 Assembly 定义和加载程序集,加载在程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例。2.使用 Module 了解如下的类似信息:包含模块的程序集以及模块中的类等。您还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。3.使用 ConstructorInfo 了解如下的类似信息:构造函数的名称、参数、访问修饰符(如 public 或 private)和实现详细信息(如 abstract 或 virtual)等。4.使用 Type 的 GetConstructors 或 GetConstructor 方法来调用特定的构造函数。5.使用 MethodInfo 来了解如下的类似信息:方法的名称、返回类型、参数、访问修饰符(如 public 或 private)和实现详细信 息(如 abstract 或 virtual)等。使用 Type 的 GetMethods 或 GetMethod 方法来调用特定的方法。6.使用 FieldInfo 来了解如下的类似信息:字段的名称、访问修饰符(如 public 或 private)和实现详细信息(如 static)等;并获取或设置字段值。7.使用 EventInfo 来了解如下的类似信息:事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等;并添加或移除事件处理程序。8.使用 PropertyInfo 来了解如下的类似信息:属性的名称、数据类型、声明类型、反射类型和只读或可写状态等;并获取或设置属性值。9.使用 ParameterInfo 来了解如下的类似信息:参数的名称、数据类型、参数是输入参数还是输出参数,以及参数在方法签名中的位置等。
收起全文
  • JAVA中的反射机制

    万次阅读 多人点赞 2014-01-08 22:35:03
    反射,当时经常听他们说,自己也看过一些资料,也可能在设计模式中使用过,但是感觉对它没有一个较深入的了解,这次重新学习了一下,感觉还行吧!  一,先看一下反射的概念:   主要是指程序可以访问,检测和...

               反射,当时经常听他们说,自己也看过一些资料,也可能在设计模式中使用过,但是感觉对它没有一个较深入的了解,这次重新学习了一下,感觉还行吧!


               一,先看一下反射的概念:

                  主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。

                 反射是java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接。但是反射使用不当会成本很高!

                 看概念很晕的,继续往下看。

     

          二,反射机制的作用:

                  1,反编译:.class-->.java

                  2,通过反射机制访问java对象的属性,方法,构造方法等;

                 这样好像更容易理解一些,下边我们具体看怎么实现这些功能。


          三,在这里先看一下sun为我们提供了那些反射机制中的类:

    java.lang.Class;                

    java.lang.reflect.Constructor; java.lang.reflect.Field;        

    java.lang.reflect.Method;

    java.lang.reflect.Modifier;


                很多反射中的方法,属性等操作我们可以从这四个类中查询。还是哪句话要学着不断的查询API,那才是我们最好的老师。


             四,具体功能实现:

                    1,反射机制获取类有三种方法,我们来获取Employee类型

    //第一种方式:
    Classc1 = Class.forName("Employee");
    //第二种方式:
    //java中每个类型都有class 属性.
    Classc2 = Employee.class;
     
    //第三种方式:
    //java语言中任何一个java对象都有getClass 方法
    Employeee = new Employee();
    Classc3 = e.getClass(); //c3是运行时类 (e的运行时类是Employee)

     

        2,创建对象:获取类以后我们来创建它的对象,利用newInstance

                Class c =Class.forName("Employee");
     
                //创建此Class 对象所表示的类的一个新实例
                Objecto = c.newInstance(); //调用了Employee的无参数构造方法.


        3,获取属性:分为所有的属性和指定的属性:

          a,先看获取所有的属性的写法:

    //获取整个类
    			Class c = Class.forName("java.lang.Integer");
    		      //获取所有的属性?
    			Field[] fs = c.getDeclaredFields();
    	 
    	               //定义可变长的字符串,用来存储属性
    			StringBuffer sb = new StringBuffer();
    	        //通过追加的方法,将每个属性拼接到此字符串中
    			//最外边的public定义
    			sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() +"{\n");
    	        //里边的每一个属性
    			for(Field field:fs){
    				sb.append("\t");//空格
    				sb.append(Modifier.toString(field.getModifiers())+" ");//获得属性的修饰符,例如public,static等等
    				sb.append(field.getType().getSimpleName() + " ");//属性的类型的名字
    				sb.append(field.getName()+";\n");//属性的名字+回车
    			}
    	
    			sb.append("}");
    	
    			System.out.println(sb);
    

           b,获取特定的属性,对比着传统的方法来学习:


    public static void main(String[] args) throws Exception{
    			
    	//以前的方式:
    	/*
    	User u = new User();
    	u.age = 12; //set
    	System.out.println(u.age); //get
    	*/
    			
    	//获取类
    	Class c = Class.forName("User");
    	//获取id属性
    	Field idF = c.getDeclaredField("id");
    	//实例化这个类赋给o
    	Object o = c.newInstance();
    	//打破封装
    	idF.setAccessible(true); //使用反射机制可以打破封装性,导致了java对象的属性不安全。
    	//给o对象的id属性赋值"110"
    	idF.set(o, "110"); //set
    	//get
    	System.out.println(idF.get(o));
    }
    

     4,获取方法,和构造方法,不再详细描述,只来看一下关键字:

    方法关键字

    含义

    getDeclaredMethods()

    获取所有的方法

    getReturnType()

    获得方法的放回类型

    getParameterTypes()

    获得方法的传入参数类型

    getDeclaredMethod("方法名",参数类型.class,……)

    获得特定的方法

     

     

    构造方法关键字

    含义

    getDeclaredConstructors()

    获取所有的构造方法

    getDeclaredConstructor(参数类型.class,……)

    获取特定的构造方法

     

     

    父类和父接口

    含义

    getSuperclass()

    获取某类的父类

    getInterfaces()

    获取某类实现的接口

      

             这样我们就可以获得类的各种内容,进行了反编译。对于JAVA这种先编译再运行的语言来说,反射机制可以使代码更加灵活,更加容易实现面向对象。

     

      五,反射加配置文件,使我们的程序更加灵活:

                 在设计模式学习当中,学习抽象工厂的时候就用到了反射来更加方便的读取数据库链接字符串等,当时不是太理解,就照着抄了。看一下.NET中的反射+配置文件的使用:

                 当时用的配置文件是app.config文件,内容是XML格式的,里边填写链接数据库的内容:

              <configuration>
    			<appSettings>
    				<add     key=""  value=""/>
    			</appSettings>
                </configuration>
    

     反射的写法:   

      assembly.load("当前程序集的名称").CreateInstance("当前命名空间名称".要实例化的类名);

     

              这样的好处是很容易的方便我们变换数据库,例如我们将系统的数据库从SQL Server升级到Oracle,那么我们写两份D层,在配置文件的内容改一下,或者加条件选择一下即可,带来了很大的方便。

                

             当然了,JAVA中其实也是一样,只不过这里的配置文件为.properties,称作属性文件。通过反射读取里边的内容。这样代码是固定的,但是配置文件的内容我们可以改,这样使我们的代码灵活了很多!


        综上为,JAVA反射的再次学习,灵活的运用它,能够使我们的代码更加灵活,但是它也有它的缺点,就是运用它会使我们的软件的性能降低,复杂度增加,所以还要我们慎重的使用它。

    展开全文
  • Java基础之—反射(非常重要)

    万次阅读 多人点赞 2017-05-17 09:49:02
    反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)) 一、反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法...

    反射是框架设计的灵魂

    (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码))

    一、反射的概述

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
    要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.


    以上的总结就是什么是反射
    反射就是把java类中的各种成分映射成一个个的Java对象
    例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。
         (其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述)
    如图是类的正常加载过程:反射的原理在与class对象。
    熟悉一下加载的时候:Class对象的由来是将class文件读入内存,并为之创建一个Class对象。



    其中这个Class对象很特殊。我们先了解一下这个Class类

    二、查看Class类在java中的api详解(1.7的API

    如何阅读java中的api详见java基础之——String字符串处理



    Class 类的实例表示正在运行的 Java 应用程序中的类和接口。也就是jvm中有N多的实例每个类都有该Class对象。(包括基本数据类型)
    Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass 方法自动构造的。也就是这不需要我们自己去处理创建,JVM已经帮我们创建好了。

    没有公共的构造方法,方法共有64个太多了。下面用到哪个就详解哪个吧



    三、反射的使用(这里使用Student类做演示)

    先写一个Student类。

    1、获取Class对象的三种方式

    1.1 Object ——> getClass();
    1.2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
    1.3 通过Class类的静态方法:forName(String  className)(常用)


    其中1.1是因为Object类中的getClass方法、因为所有类都继承Object类。从而调用Object类来获取


    package fanshe;
    /**
     * 获取Class对象的三种方式
     * 1 Object ——> getClass();
     * 2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
     * 3 通过Class类的静态方法:forName(String  className)(常用)
     *
     */
    public class Fanshe {
    	public static void main(String[] args) {
    		//第一种方式获取Class对象  
    		Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。
    		Class stuClass = stu1.getClass();//获取Class对象
    		System.out.println(stuClass.getName());
    		
    		//第二种方式获取Class对象
    		Class stuClass2 = Student.class;
    		System.out.println(stuClass == stuClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个
    		
    		//第三种方式获取Class对象
    		try {
    			Class stuClass3 = Class.forName("fanshe.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
    			System.out.println(stuClass3 == stuClass2);//判断三种方式是否获取的是同一个Class对象
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		}
    		
    	}
    }

    注意:在运行期间,一个类,只有一个Class对象产生。

    三种方式常用第三种,第一种对象都有了还要反射干什么。第二种需要导入类的包,依赖太强,不导包就抛编译错误。一般都第三种,一个字符串可以传入也可写在配置文件中等多种方法。

    2、通过反射获取构造方法并使用:

    student类:
    package fanshe;
    
    public class Student {
    	
    	//---------------构造方法-------------------
    	//(默认的构造方法)
    	Student(String str){
    		System.out.println("(默认)的构造方法 s = " + str);
    	}
    	
    	//无参构造方法
    	public Student(){
    		System.out.println("调用了公有、无参构造方法执行了。。。");
    	}
    	
    	//有一个参数的构造方法
    	public Student(char name){
    		System.out.println("姓名:" + name);
    	}
    	
    	//有多个参数的构造方法
    	public Student(String name ,int age){
    		System.out.println("姓名:"+name+"年龄:"+ age);//这的执行效率有问题,以后解决。
    	}
    	
    	//受保护的构造方法
    	protected Student(boolean n){
    		System.out.println("受保护的构造方法 n = " + n);
    	}
    	
    	//私有构造方法
    	private Student(int age){
    		System.out.println("私有的构造方法   年龄:"+ age);
    	}
    
    }
    

    共有6个构造方法;

    测试类:
    package fanshe;
    
    import java.lang.reflect.Constructor;
    
    
    /*
     * 通过Class对象可以获取某个类中的:构造方法、成员变量、成员方法;并访问成员;
     * 
     * 1.获取构造方法:
     * 		1).批量的方法:
     * 			public Constructor[] getConstructors():所有"公有的"构造方法
                public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
         
     * 		2).获取单个的方法,并调用:
     * 			public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
     * 			public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
     * 		
     * 			调用构造方法:
     * 			Constructor-->newInstance(Object... initargs)
     */
    public class Constructors {
    
    	public static void main(String[] args) throws Exception {
    		//1.加载Class对象
    		Class clazz = Class.forName("fanshe.Student");
    		
    		
    		//2.获取所有公有构造方法
    		System.out.println("**********************所有公有构造方法*********************************");
    		Constructor[] conArray = clazz.getConstructors();
    		for(Constructor c : conArray){
    			System.out.println(c);
    		}
    		
    		
    		System.out.println("************所有的构造方法(包括:私有、受保护、默认、公有)***************");
    		conArray = clazz.getDeclaredConstructors();
    		for(Constructor c : conArray){
    			System.out.println(c);
    		}
    		
    		System.out.println("*****************获取公有、无参的构造方法*******************************");
    		Constructor con = clazz.getConstructor(null);
    		//1>、因为是无参的构造方法所以类型是一个null,不写也可以:这里需要的是一个参数的类型,切记是类型
    		//2>、返回的是描述这个无参构造函数的类对象。
    	
    		System.out.println("con = " + con);
    		//调用构造方法
    		Object obj = con.newInstance();
    	//	System.out.println("obj = " + obj);
    	//	Student stu = (Student)obj;
    		
    		System.out.println("******************获取私有构造方法,并调用*******************************");
    		con = clazz.getDeclaredConstructor(char.class);
    		System.out.println(con);
    		//调用构造方法
    		con.setAccessible(true);//暴力访问(忽略掉访问修饰符)
    		obj = con.newInstance('男');
    	}
    	
    }
    

    后台输出:
    **********************所有公有构造方法*********************************
    public fanshe.Student(java.lang.String,int)
    public fanshe.Student(char)
    public fanshe.Student()
    ************所有的构造方法(包括:私有、受保护、默认、公有)***************
    private fanshe.Student(int)
    protected fanshe.Student(boolean)
    public fanshe.Student(java.lang.String,int)
    public fanshe.Student(char)
    public fanshe.Student()
    fanshe.Student(java.lang.String)
    *****************获取公有、无参的构造方法*******************************
    con = public fanshe.Student()
    调用了公有、无参构造方法执行了。。。
    ******************获取私有构造方法,并调用*******************************
    public fanshe.Student(char)
    姓名:男

    调用方法:
    1.获取构造方法:
      1).批量的方法:
    public Constructor[] getConstructors():所有"公有的"构造方法
                public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
         
      2).获取单个的方法,并调用:
    public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
    public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;

      调用构造方法:
    Constructor-->newInstance(Object... initargs)

    2、newInstance是 Constructor类的方法(管理构造函数的类)
    api的解释为:
    newInstance(Object... initargs)
               使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。
    它的返回值是T类型,所以newInstance是创建了一个构造方法的声明类的新实例对象。并为之调用

    3、获取成员变量并调用

    student类:
    package fanshe.field;
    
    public class Student {
    	public Student(){
    		
    	}
    	//**********字段*************//
    	public String name;
    	protected int age;
    	char sex;
    	private String phoneNum;
    	
    	@Override
    	public String toString() {
    		return "Student [name=" + name + ", age=" + age + ", sex=" + sex
    				+ ", phoneNum=" + phoneNum + "]";
    	}
    	
    	
    }


    测试类:
    package fanshe.field;
    import java.lang.reflect.Field;
    /*
     * 获取成员变量并调用:
     * 
     * 1.批量的
     * 		1).Field[] getFields():获取所有的"公有字段"
     * 		2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;
     * 2.获取单个的:
     * 		1).public Field getField(String fieldName):获取某个"公有的"字段;
     * 		2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)
     * 
     * 	 设置字段的值:
     * 		Field --> public void set(Object obj,Object value):
     * 					参数说明:
     * 					1.obj:要设置的字段所在的对象;
     * 					2.value:要为字段设置的值;
     * 
     */
    public class Fields {
    
    		public static void main(String[] args) throws Exception {
    			//1.获取Class对象
    			Class stuClass = Class.forName("fanshe.field.Student");
    			//2.获取字段
    			System.out.println("************获取所有公有的字段********************");
    			Field[] fieldArray = stuClass.getFields();
    			for(Field f : fieldArray){
    				System.out.println(f);
    			}
    			System.out.println("************获取所有的字段(包括私有、受保护、默认的)********************");
    			fieldArray = stuClass.getDeclaredFields();
    			for(Field f : fieldArray){
    				System.out.println(f);
    			}
    			System.out.println("*************获取公有字段**并调用***********************************");
    			Field f = stuClass.getField("name");
    			System.out.println(f);
    			//获取一个对象
    			Object obj = stuClass.getConstructor().newInstance();//产生Student对象--》Student stu = new Student();
    			//为字段设置值
    			f.set(obj, "刘德华");//为Student对象中的name属性赋值--》stu.name = "刘德华"
    			//验证
    			Student stu = (Student)obj;
    			System.out.println("验证姓名:" + stu.name);
    			
    			
    			System.out.println("**************获取私有字段****并调用********************************");
    			f = stuClass.getDeclaredField("phoneNum");
    			System.out.println(f);
    			f.setAccessible(true);//暴力反射,解除私有限定
    			f.set(obj, "18888889999");
    			System.out.println("验证电话:" + stu);
    			
    		}
    	}
    

    后台输出:

    ************获取所有公有的字段********************
    public java.lang.String fanshe.field.Student.name
    ************获取所有的字段(包括私有、受保护、默认的)********************
    public java.lang.String fanshe.field.Student.name
    protected int fanshe.field.Student.age
    char fanshe.field.Student.sex
    private java.lang.String fanshe.field.Student.phoneNum
    *************获取公有字段**并调用***********************************
    public java.lang.String fanshe.field.Student.name
    验证姓名:刘德华
    **************获取私有字段****并调用********************************
    private java.lang.String fanshe.field.Student.phoneNum
    验证电话:Student [name=刘德华, age=0, sex=

    由此可见
    调用字段时:需要传递两个参数:
    Object obj = stuClass.getConstructor().newInstance();//产生Student对象--》Student stu = new Student();
    //为字段设置值
    f.set(obj, "刘德华");//为Student对象中的name属性赋值--》stu.name = "刘德华"
    第一个参数:要传入设置的对象,第二个参数:要传入实参

    4、获取成员方法并调用

    student类:
    package fanshe.method;
    
    public class Student {
    	//**************成员方法***************//
    	public void show1(String s){
    		System.out.println("调用了:公有的,String参数的show1(): s = " + s);
    	}
    	protected void show2(){
    		System.out.println("调用了:受保护的,无参的show2()");
    	}
    	void show3(){
    		System.out.println("调用了:默认的,无参的show3()");
    	}
    	private String show4(int age){
    		System.out.println("调用了,私有的,并且有返回值的,int参数的show4(): age = " + age);
    		return "abcd";
    	}
    }
    

    测试类:
    package fanshe.method;
    
    import java.lang.reflect.Method;
    
    /*
     * 获取成员方法并调用:
     * 
     * 1.批量的:
     * 		public Method[] getMethods():获取所有"公有方法";(包含了父类的方法也包含Object类)
     * 		public Method[] getDeclaredMethods():获取所有的成员方法,包括私有的(不包括继承的)
     * 2.获取单个的:
     * 		public Method getMethod(String name,Class<?>... parameterTypes):
     * 					参数:
     * 						name : 方法名;
     * 						Class ... : 形参的Class类型对象
     * 		public Method getDeclaredMethod(String name,Class<?>... parameterTypes)
     * 
     * 	 调用方法:
     * 		Method --> public Object invoke(Object obj,Object... args):
     * 					参数说明:
     * 					obj : 要调用方法的对象;
     * 					args:调用方式时所传递的实参;
    
    ):
     */
    public class MethodClass {
    
    	public static void main(String[] args) throws Exception {
    		//1.获取Class对象
    		Class stuClass = Class.forName("fanshe.method.Student");
    		//2.获取所有公有方法
    		System.out.println("***************获取所有的”公有“方法*******************");
    		stuClass.getMethods();
    		Method[] methodArray = stuClass.getMethods();
    		for(Method m : methodArray){
    			System.out.println(m);
    		}
    		System.out.println("***************获取所有的方法,包括私有的*******************");
    		methodArray = stuClass.getDeclaredMethods();
    		for(Method m : methodArray){
    			System.out.println(m);
    		}
    		System.out.println("***************获取公有的show1()方法*******************");
    		Method m = stuClass.getMethod("show1", String.class);
    		System.out.println(m);
    		//实例化一个Student对象
    		Object obj = stuClass.getConstructor().newInstance();
    		m.invoke(obj, "刘德华");
    		
    		System.out.println("***************获取私有的show4()方法******************");
    		m = stuClass.getDeclaredMethod("show4", int.class);
    		System.out.println(m);
    		m.setAccessible(true);//解除私有限定
    		Object result = m.invoke(obj, 20);//需要两个参数,一个是要调用的对象(获取有反射),一个是实参
    		System.out.println("返回值:" + result);
    		
    		
    	}
    }
    
    控制台输出:
    ***************获取所有的”公有“方法*******************
    public void fanshe.method.Student.show1(java.lang.String)
    public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
    public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
    public final void java.lang.Object.wait() throws java.lang.InterruptedException
    public boolean java.lang.Object.equals(java.lang.Object)
    public java.lang.String java.lang.Object.toString()
    public native int java.lang.Object.hashCode()
    public final native java.lang.Class java.lang.Object.getClass()
    public final native void java.lang.Object.notify()
    public final native void java.lang.Object.notifyAll()
    ***************获取所有的方法,包括私有的*******************
    public void fanshe.method.Student.show1(java.lang.String)
    private java.lang.String fanshe.method.Student.show4(int)
    protected void fanshe.method.Student.show2()
    void fanshe.method.Student.show3()
    ***************获取公有的show1()方法*******************
    public void fanshe.method.Student.show1(java.lang.String)
    调用了:公有的,String参数的show1(): s = 刘德华
    ***************获取私有的show4()方法******************
    private java.lang.String fanshe.method.Student.show4(int)
    调用了,私有的,并且有返回值的,int参数的show4(): age = 20
    返回值:abcd

    由此可见:
    m = stuClass.getDeclaredMethod("show4", int.class);//调用制定方法(所有包括私有的),需要传入两个参数,第一个是调用的方法名称,第二个是方法的形参类型,切记是类型。
    System.out.println(m);
    m.setAccessible(true);//解除私有限定
    Object result = m.invoke(obj, 20);//需要两个参数,一个是要调用的对象(获取有反射),一个是实参
    System.out.println("返回值:" + result);
    //

    控制台输出:
    ***************获取所有的”公有“方法*******************
    public void fanshe.method.Student.show1(java.lang.String)
    public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
    public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
    public final void java.lang.Object.wait() throws java.lang.InterruptedException
    public boolean java.lang.Object.equals(java.lang.Object)
    public java.lang.String java.lang.Object.toString()
    public native int java.lang.Object.hashCode()
    public final native java.lang.Class java.lang.Object.getClass()
    public final native void java.lang.Object.notify()
    public final native void java.lang.Object.notifyAll()
    ***************获取所有的方法,包括私有的*******************
    public void fanshe.method.Student.show1(java.lang.String)
    private java.lang.String fanshe.method.Student.show4(int)
    protected void fanshe.method.Student.show2()
    void fanshe.method.Student.show3()
    ***************获取公有的show1()方法*******************
    public void fanshe.method.Student.show1(java.lang.String)
    调用了:公有的,String参数的show1(): s = 刘德华
    ***************获取私有的show4()方法******************
    private java.lang.String fanshe.method.Student.show4(int)
    调用了,私有的,并且有返回值的,int参数的show4(): age = 20
    返回值:abcd

    其实这里的成员方法:在模型中有属性一词,就是那些setter()方法和getter()方法。还有字段组成,这些内容在内省中详解

    5、反射main方法

    student类:
    package fanshe.main;
    
    public class Student {
    
    	public static void main(String[] args) {
    		System.out.println("main方法执行了。。。");
    	}
    }
    


    测试类:
    package fanshe.main;
    
    import java.lang.reflect.Method;
    
    /**
     * 获取Student类的main方法、不要与当前的main方法搞混了
     */
    public class Main {
    	
    	public static void main(String[] args) {
    		try {
    			//1、获取Student对象的字节码
    			Class clazz = Class.forName("fanshe.main.Student");
    			
    			//2、获取main方法
    			 Method methodMain = clazz.getMethod("main", String[].class);//第一个参数:方法名称,第二个参数:方法形参的类型,
    			//3、调用main方法
    			// methodMain.invoke(null, new String[]{"a","b","c"});
    			 //第一个参数,对象类型,因为方法是static静态的,所以为null可以,第二个参数是String数组,这里要注意在jdk1.4时是数组,jdk1.5之后是可变参数
    			 //这里拆的时候将  new String[]{"a","b","c"} 拆成3个对象。。。所以需要将它强转。
    			 methodMain.invoke(null, (Object)new String[]{"a","b","c"});//方式一
    			// methodMain.invoke(null, new Object[]{new String[]{"a","b","c"}});//方式二
    			
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		
    		
    	}
    }
    

    控制台输出:
    main方法执行了。。。

    6、反射方法的其它使用之---通过反射运行配置文件内容

    student类:
    public class Student {
    	public void show(){
    		System.out.println("is show()");
    	}
    }

    配置文件以txt文件为例子(pro.txt):
    className = cn.fanshe.Student
    methodName = show

    测试类:
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.lang.reflect.Method;
    import java.util.Properties;
    
    /*
     * 我们利用反射和配置文件,可以使:应用程序更新时,对源码无需进行任何修改
     * 我们只需要将新类发送给客户端,并修改配置文件即可
     */
    public class Demo {
    	public static void main(String[] args) throws Exception {
    		//通过反射获取Class对象
    		Class stuClass = Class.forName(getValue("className"));//"cn.fanshe.Student"
    		//2获取show()方法
    		Method m = stuClass.getMethod(getValue("methodName"));//show
    		//3.调用show()方法
    		m.invoke(stuClass.getConstructor().newInstance());
    		
    	}
    	
    	//此方法接收一个key,在配置文件中获取相应的value
    	public static String getValue(String key) throws IOException{
    		Properties pro = new Properties();//获取配置文件的对象
    		FileReader in = new FileReader("pro.txt");//获取输入流
    		pro.load(in);//将流加载到配置文件对象中
    		in.close();
    		return pro.getProperty(key);//返回根据key获取的value值
    	}
    }
    

    控制台输出:
    is show()

    需求:
    当我们升级这个系统时,不要Student类,而需要新写一个Student2的类时,这时只需要更改pro.txt的文件内容就可以了。代码就一点不用改动

    要替换的student2类:
    public class Student2 {
    	public void show2(){
    		System.out.println("is show2()");
    	}
    }

    配置文件更改为:
    className = cn.fanshe.Student2
    methodName = show2
    控制台输出:
    is show2();

    7、反射方法的其它使用之---通过反射越过泛型检查

    泛型用在编译期,编译过后泛型擦除(消失掉)。所以是可以通过反射越过泛型检查的
    测试类:
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    
    /*
     * 通过反射越过泛型检查
     * 
     * 例如:有一个String泛型的集合,怎样能向这个集合中添加一个Integer类型的值?
     */
    public class Demo {
    	public static void main(String[] args) throws Exception{
    		ArrayList<String> strList = new ArrayList<>();
    		strList.add("aaa");
    		strList.add("bbb");
    		
    	//	strList.add(100);
    		//获取ArrayList的Class对象,反向的调用add()方法,添加数据
    		Class listClass = strList.getClass(); //得到 strList 对象的字节码 对象
    		//获取add()方法
    		Method m = listClass.getMethod("add", Object.class);
    		//调用add()方法
    		m.invoke(strList, 100);
    		
    		//遍历集合
    		for(Object obj : strList){
    			System.out.println(obj);
    		}
    	}
    }

    控制台输出:
    aaa
    bbb
    100

    //反射就总结到这,下面的内省章节也和反射有关,可以算是反射的高级使用吧,如果有兴趣,可以继续查看总结的内省部分。


    展开全文
  • 什么是反射反射可以做些什么

    千次阅读 2018-07-09 18:52:00
    阅读目录 什么是反射反射能干嘛?获取类型的相关信息获取类型本身信息(命名空间名、全名、是否是抽象、是否是类、、...获取类型成员信息(通过Tyep中的方法GetMembers)动态调用方法调用方式一(使用InvokeMember...

    什么是反射,反射能干嘛?

    反射是:指程序可以访问、检测和修改它本身状态或行为的一种能力

    反射是一种能力,所以给的定义就是说明了它能干嘛。

    我们平时用反射主要做:

    • 获取类型的相关信息
    • 动态调用方法
    • 动态构造对象
    • 从程序集中获得类型

    获取类型的相关信息

    反射的核心Type类,Type对象提供的属性和方法可以获取对象的一切信息,如:方法、字段、属性、事件...等等。

    我们获取已加载程序集中类型的Type对象的几种方法:(以StringBuilder 类型为例)

    1. 直接使用typeof操作符 Type T1 = typeof(StringBuilder); 
    2. 通过类型实例 Type T2 = new StringBuilder().GetType(); 
    3. 通过Type类的静态方法 Type T3 = Type.GetType("System.IO.Stream"); 

    不管使用那种,我们最终得到的结果都是一样的。

    那么我们通过Type又能得到些什么信息呢?

    获取类型本身信息(命名空间名、全名、是否是抽象、是否是类、、、等等

    复制代码
    var T1 = typeof(StringBuilder);                      
    Console.WriteLine("命名空间名称:" + T1.Namespace);
    Console.WriteLine("直接基类型:" + T1.BaseType);
    Console.WriteLine("全名:" + T1.FullName);
    Console.WriteLine("是抽象类型:" + T1.IsAbstract);
    Console.WriteLine("是类:" + T1.IsClass);
    //.....等等
    复制代码

    获取类型成员信息(通过Tyep中的方法GetMembers)

    复制代码
    Type T1 = typeof(TClass);
    var Mets = T1.GetMembers();//获取Type对象的所有公有成员           
    foreach (var m in Mets)
    {
        Console.WriteLine("" + m.MemberType.ToString()+ "】:" + m.Name);
        // m.MemberType 是成员类型
    }
    复制代码

    MemberType所能包含的成员类型有哪些呢?如:(可以自己可以F12进去看看)

    注意:其中MemberInfo的属性DeclaringType返回的是这个属性定义的类型,而ReflectedType返回的是获取这个属性的对象类型。

    如:

    复制代码
    Type T2 = typeof(TClass);
    var Mets = T2.GetMembers();//获取所有公共成员(返回值是MemberInfo类型集合)
    foreach (var m in Mets)
    {
        if (m.Name=="Equals")
        {
            Console.WriteLine("" + m.MemberType.ToString() + "】:" + m.Name);
            // m.MemberType 是成员类型
    
            // m.DeclaringType;//获取申明该成员的类
            // m.ReflectedType;//获取用于获取 MemberInfo 的此实例的类对象。 
    
        } 
    }
    复制代码

    T2中的Equals,我们知道这个方式是在Objec中定义的,在TClass中调用的,所以:

    我们发现获取Type对象的成员大多都是以 isxxx、Getxxx、Getxxxs格式的。

    isxxx格式的基本上都是判断是否是某类型。

    Getxxx和Getxxxs都是放回某类型和某类型集合。其中主要的类型有:

    复制代码
    //FieldInfo封装了关于字段的所有信息   (通过Tyep对象的GetFields或GetField方法)
    
    //PropertyInfo类型,封装了类型的属性信息;(通过Type对象的GetProperties或GetProperty方法)
    
    //ConstructorInfo类型,封装了类型的构造函数信息; (..........)
    
    //MethodInfo类型,封装了类型的方法信息;  (........)
    
    //MemberInfo类型,封装了类型的所有公共成员;(**就是我们上面说的GetMembers方法**)
    
    //EventInfo类型,封装了类型的事件信息;(.......)
    
    //ParameterInfo类型,封装了方法和构造函数的参数信息;(........)
    复制代码

    它们都在 System.Reflection 命名空间下,其每个isxxx、Getxxx、Getxxxs的细节实例用法就不一一演示了。和上面的GetMembers用法区别不大。

    动态调用方法

    首先定义个类:

    复制代码
    public class TClass
    {
        public void fun(string str)
        {
            Console.WriteLine("我是fun方法,我被调用了。" + str);
        }
        public void fun2()
        {
            Console.WriteLine("我是fun2方法,我被调用了。");
        }
    
        public static void fun3()
        {
            Console.WriteLine("我是fun3静态方法,我被调用了");
        }
    }
    复制代码

    调用方式一(使用InvokeMember调用方法)

    调用带参实例方法fun

    Type T1 = typeof(TClass);
    T1.InvokeMember("fun", BindingFlags.InvokeMethod, null, new TClass(), new string[] { "test" });

    调用无参实例方法fun2

    Type T1 = typeof(TClass);
    T1.InvokeMember("fun2", BindingFlags.InvokeMethod, null, new TClass(), null);

    调用静态方法

    Type T1 = typeof(TClass);
    T1.InvokeMember("fun3", BindingFlags.InvokeMethod, null, T1, null);

    我们发现了一个问题当我们调用实例方法的时候需要传实例对象过去。(有人会说,都实例对象了,我还要你动态掉调用个屁啊。有种情况,在我们实例了对象后,仍不确定应该调用那个方法时可以只有使用。然后有人有说了,那如果实例对象我也不确定呢?那我们下面会分析连实例对象也给动态了。那接着完下看吧。

    我们来说下这几个参数的意思吧。

    第一个:要被动态调用的方法名。

    第二个:是一个枚举,表示是调用一个方法

    第三个:是Binder,传的是null,使用默认值。

    第四个:传如实例对象(调用实例方法时)或者Type对象(调用静态方法时)。

    第五个:要传给被调用发的参数数组。

    调用方式二(使用MethodInfo.Invoke调用方法)

    Type T1 = typeof(TClass);
    T1.GetMethod("fun", BindingFlags.Instance | BindingFlags.Public).Invoke(new TClass(), new string[] { "testfun1" });
    T1.GetMethod("fun2", BindingFlags.Instance | BindingFlags.Public).Invoke(new TClass(), null);
    T1.GetMethod("fun3", BindingFlags.Static | BindingFlags.Public).Invoke(T1, null);

     

    使用其实和上面的方式一区别不大。

    真正的全动态调用

    上面的两种方式,在编写代码的时候总是要先确定了已知的对象名和方法名。那么我们在不知道对象和方法名的时候是否也可以调用呢?答案是肯定的,实现如下:

    复制代码
    Console.WriteLine("请输入对象类名");
    string className = Console.ReadLine();
    Console.WriteLine("请输入要执行的方法名");
    
    string funName = Console.ReadLine();
    Type T1 = Type.GetType(className);
    
    ConstructorInfo ci = T1.GetConstructors()[0]; //获取构造函数 
    var obj = ci.Invoke(null);//实例化构造函数
    
    T1.InvokeMember(funName, BindingFlags.InvokeMethod, null, obj, null);
    复制代码

    当然,这个代码只能只是fun2,因为上面的传参写死了。(你也可以自己稍微修改下,就可以执行fun、fun2、fun3了) 

    效果如下:(对象名和方法名都是手动输入的

    动态构造对象

    我们先定义一个对象:

    复制代码
    public class TClass
    {
        public TClass()
        {
            Console.WriteLine("构造函数被执行了。。");
        }
        public TClass(string str)
        {
            Console.WriteLine("有参构造函数被执行了。。" + str);
        }        
    }
    复制代码

    动态构造对象

    复制代码
    //动态构造对象,方式一
    Assembly asm = Assembly.GetExecutingAssembly();
    TClass obj = (TClass)asm.CreateInstance("net.tclass", true);//true:不区分大小写
    
    //动态构造对象,方式二
    ObjectHandle handler = Activator.CreateInstance(null, " net.TClass");//null:当前程序集
    obj = (TClass)handler.Unwrap();
    
    //动态构造对象,方式三(构造有参构造函数)
    Assembly asm2 = Assembly.GetExecutingAssembly();
    obj = (TClass)asm2.CreateInstance("net.tclass", true, BindingFlags.Default, null, new string[] { "test" }, null, null);//true:不区分大小写            
    复制代码

    执行效果图:

    获取和修改属性

    复制代码
    var obj = new TClass();
    obj.name = "张三";
    Type type = typeof(TClass);
    //获取属性
    var Name = type.InvokeMember("name", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null,
                         obj, new object[] { }) as string;
    Console.WriteLine(obj.name);
    //设置属性
    type.InvokeMember("name", BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance, null,
                          obj, new object[] { "新属性(李四)" });
    Console.WriteLine(obj.name);
    
    //=====================
    
    PropertyInfo[] pros = type.GetProperties(---);//
    PropertyInfo pro = null;
    
    var value = pro.GetValue(type);//获取值
    复制代码

    从程序集中获得类型

    取得当前代码所在程序集(使用GetExecutingAssembly)

    Assembly ass = Assembly.GetExecutingAssembly();
    Console.WriteLine("当前所在程序集名:"+ass.ManifestModule.Name);
    Console.WriteLine("当前所在程序集路径:"+ass.Location);

     

    通过反射加载程序集并创建程序中的类型对象

    从程序集中获得类型,这个应该是我们平时用得比较多。如我们所谓的依赖注入和控制反转(这个主题将在下篇博文进行分析)就用到了通过反射从程序集中获取类型。

    首先我们还是看看怎么从程序集中获得类型吧。我们可以使用Assembly类型提供的静态方法LoadFrom()或Load(),如:

    Assembly asm = Assembly.LoadFrom("Demo.dll");
    Assembly asm = Assembly.Load("Demo");

    区别:

    复制代码
    Assembly asm = Assembly.LoadFrom("net.exe");//需要加后缀,可以指定路径,如下面的
    Assembly asm1 = Assembly.LoadFrom(@"C:\01文件\05Svn\BlogsCode\Blogs\Blogs.Web\bin\Blogs.BLL.dll");
    
    Assembly asm2 = Assembly.Load("Blogs.BLL");//无需加后缀,不可以指定路径
    //Assembly asm3 = Assembly.Load(@"C:\01文件\05Svn\BlogsCode\Blogs\Blogs.Web\bin\Blogs.BLL");//这里会报错
    //使用Load可以加载当前程序bin目录行下的程序集或者系统程序集
    
    //这里TClass可以是一个接口,那么可以在外面的dll任意实现了。  
    TClass obj = (TClass)asm2.CreateInstance("net.tclass", true);//true:不区分大小写
    obj.fun();//***调用动态加载的dll中的方法***
    复制代码

    这样带来的功能是非常强大的。如 我们在没有引用程序集的情况下,也可以使用到程序外的程序集。我们还可以根据不同情况引用不同的程序集。我们甚至还可以通过配置文件来直接配置代码运行时应该加载哪个dll,运行哪个dll中的哪个实现方法。(下篇在讲依赖注入的时候会讲到,同学们继续关注哦~)

    从上所知,反射不是某一个概念,而是一类操作的统称。或者说是某些能力的统称。 感觉不好回答反射到底是什么,只能说反射能干什么。它能动态创建对象、动态调用对象方法、动态读取和设置属性和字段、它能动态加载程序外的dll。总的感觉就是大多数都是跟“动态”扯上了关系。

     


     

    补充:跨程序集反射

    如果我们反射A.dll,而A.dll中引用了B.dll,那么在assembly.GetTypes(); //运行到这个地方会弹出如下错误描述

     

    “未处理 System.Reflection.ReflectionTypeLoadException Message="无法加载一个或多个请求的类型。有关更多信息,请检索LoaderExceptions属性。”

     

    这种情况可以

     

    Assembly assembly =  Assembly.LoadFrom("A.dll") ;
    Type type = assembly.GetType("xxx.myclassname") ; //传入对应的需要反射的类型 而不能GetTypes。且,应用程序需要应用A.dll锁依赖的B.dll。

     


    展开全文
  • 什么是反射

    千次阅读 2019-04-27 11:30:18
    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。...

           JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

    Class类

    这个类用于操纵(反向解析)一个类的属性,方法,构造器等。

    Person: name,age,address(Class只要知道你这个Person类,那么它便可知道你所有的属性,不止属性,甚至方法上的注解等等,都会知道。)

    范例:获取一个Class对象

    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.Arrays;
    
    public class Test01 {
        public static void main(String[] args) throws ClassNotFoundException {
            String a = "java.lang.String";
    //        String a = "java.lang.HashMap";
    
            // 根据一类的全名字符串来获得一个类的类对象
            Class<?> clazz = Class.forName(a);
            // 获得传递过来的类的所有方法
            Method[] methods = clazz.getDeclaredMethods();
    //        String s = Arrays.toString(methods);
            for (Method m: methods) {
                System.out.println(m);
            }
            System.out.println("------------------------------------------");
            // 获得类的所有属性
            Field[] declaredFields = clazz.getDeclaredFields();
            for(Field d : declaredFields) {
                System.out.println(d);
            }
            System.out.println("-------------------------------------");
            // 获得类的所有构造器
            Constructor<?>[] constructors = clazz.getDeclaredConstructors();
            for (Constructor c : constructors) {
                System.out.println(c);
            }
        }
    }

     

    展开全文
  • java进阶技术:泛型、反射、注解

    千人学习 2018-10-22 21:38:16
    JAVA反射机制是构建框架技术的基础所在。灵活掌握Java反射机制,对以后学习框架有很大的帮助。 注解(Annotation)是JDK1.5及以后引入的新特性,与类、接口、枚举是在同一个层次。可声明在包、类、字段、方法、局部...
  • 反射

    2020-04-03 21:45:50
    通过反射查看类信息 大部分对象在不同情况下是不同类型的,可能编译和运行时的类型是不同的,可能用到它时它的类型不是我们所需要的那个类型。解决这一问题通常有如下两种方法: 1.第一种做法是假设在编译时和运行时...
  • 反射的原理及应用

    万次阅读 2018-12-28 14:57:19
    1,类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实 现对这个类进行初始化。 加载 就是指将 class 文件读入内存,并为之创建一个 Class 对象。...
  • 什么是内存屏障

    2019-06-23 14:03:12
    内存屏障是指“由于编译器的优化和缓存的使用,导致对内存的写入操作不能及时的反应出来,也就是说当完成对内存的写入操作之后,读取出来的可能是旧的内容”(摘自《独辟蹊径品内核》)。(这里概念貌似不是很准确,...
  • Java反射技术详解

    万次阅读 多人点赞 2020-06-19 09:27:58
    相信很多人都知道反射可以说是Java中最强大的技术了,它可以做的事情太多太多,很多优秀的开源框架都是通过反射完成的,比如最初的很多注解框架,后来因为java反射影响性能,所以被运行时注解APT替代了,java反射有...
  • 用最直接的大白话来聊一聊Java中的反射机制

    万次阅读 多人点赞 2020-08-24 09:41:28
    思考:在讲反射之前,先思考一个问题,java中如何创建一个对象,有哪几种方式? Java中创建对象大概有这几种方式: 1、使用new关键字:这是我们最常见的也是最简单的创建对象的方式 2、使用Clone的方法:无论何时...
  • Java基础篇:反射机制详解

    万次阅读 多人点赞 2019-12-03 23:51:20
    一、什么是反射反射是Java的特征之一,是一种间接操作目标对象的机制,核心是JVM在运行的时候才动态加载类,并且对于任意一个类,都能够知道这个类的所有属性和方法,调用方法/访问属性,不需要提前在编译期...
  • 面试官:反射都不会,还敢说自己会Java?

    万次阅读 多人点赞 2020-04-29 15:50:03
    一、反射机制 1.1 框架   在学习Java的路上,相信你一定使用过各种各样的框架。所谓的框架就是一个半成品软件,已经对基础的代码进行了封装并提供相应的API。在框架的基础上进行软件开发,可以简化编码。学习使用...
  • 深入理解Java类型信息(Class对象)与反射机制

    万次阅读 多人点赞 2018-01-07 11:34:00
    【版权申明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) ...深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解
  • Java核心:第一章:Java反射

    万次阅读 多人点赞 2020-09-03 09:29:26
    首先学习反射之前,我要提出疑问: 反射是个什么东西?它是用来做什么的?为啥要用它?它有什么优缺点?它的工作原理是什么?平时的应用场景有哪些?我怎么使用它?(何时用,怎么用,为啥要用等等) 这么多的问题...
  • 浅析Java中的反射机制原理

    万次阅读 多人点赞 2015-11-20 15:24:21
    反射反射,程序员的快乐!  Java中反射机制使用的还是比较广泛的,系统的灵活性、可扩展性大都都是通过反射等方式来加载外部插件,使得系统与插件解耦的同时,增加了功能。但是很多人都只是会用,却是不知道它的...
  • Java笔试面试-反射和动态代理

    万次阅读 多人点赞 2020-04-19 17:37:39
    反射   反射机制是 Java 语言提供的一种基础功能,赋予程序在运行时自省(introspect)的能力。简单来说就是通过反射,可以在运行期间获取、检测和调用对象的属性和方法。 反射的使用场景 1.编程工具 IDEA 或 ...
  • Java反射机制的原理和用途

    万次阅读 多人点赞 2019-03-03 08:16:12
    看了好多关于Java反射机制的文章,大多都太过官方,消化起来比较稍显费劲,本篇,我会依据自己的理解去阐述什么是Java的反射机制,反射用在什么地方,以及怎么来使用? 开篇前,我们还是要了解一下,什么是Java的...
  • Java反射的作用

    万次阅读 多人点赞 2012-07-19 21:14:49
    Java的反射机制是Java特性之一,反射机制是构建框架技术的基础所在。灵活掌握Java反射机制,对大家以后学习框架技术有很大的帮助。 那么什么是Java的反射呢?  大家都知道,要让Java程序能够运行,那么就得让Java...
  • Java 反射机制详解

    万次阅读 2019-08-09 21:53:12
    因为在 Android 开发的过程中, 泛型,反射,注解这些知识进场会用到,几乎所有的框架至少都会用到上面的一两种知识,如 Gson 就用到泛型,反射,注解,Retrofit 也用到泛型,反射,注解 。学好这些知识对我们进阶...
  • Java 反射和映射(主要描述下反射)

    千次阅读 2020-07-20 11:25:29
    什么是反射?等同于映射吗? 完全不相关的。反射是一个机机制,映射是一种关系。 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和...
1 2 3 4 5 ... 20
收藏数 461,991
精华内容 184,796
关键字:

反射