java反射机制_java反射机制详解 - CSDN
精华内容
参与话题
  • java中的反射机制(重要)

    千次阅读 2018-08-16 15:03:10
    1.JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法; 2.对于任意一个对象,都能够调用它的任意方法和属性; 3.这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制...

                                                 java中反射

    一、反射的含义及作用

    1.JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;

    2.对于任意一个对象,都能够调用它的任意方法和属性;

    3.这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制

    二、如何得到反射(以包名为test中的Student类为示例)

    package test;
    
    public class Student {
    	public Student(){
    		
    	}
    	public Student(int num,String name){
    		
    	}
    	private int num;
    	
    	public String name;
    	
    	protected String address;
    }
    

    1.获得类的对象,用对象.getclass();

          Student st=new Student();

          st.getclass();

    2.类名.class;

           Student.class;

    3.Class.forName("包名、类名");

          Class.forName("test、Student");

    三、具体反射类中的构造器,属性、方法

                                                                             获取类中的构造器即public Student(){}

        //测试类中的代码
            Class c=Student.class;
    		//getConstructors只能获得公共构造器//getDeclaredConstructors获得所有构造器
            //constructor是获取构造器时所用
    		Constructor[] cs= c.getConstructors;
    		for (Constructor constructor : cs) {
    		Student st=(Student)constructor.newInstance();
    		System.out.println(st);
    }
    
    		

                                                                               获取类中的属性(num,name,address)

    public class Test{
        
           public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            //获得反射,获取属性的关键代码
    
            Class c=Student.class;
    		Field[] fs=	c.getDeclaredFields();
    		for (Field field : fs) {
    			System.out.println(field);
    		}
           //输出的结果为
           /*   private int com.qm.test.Student.num
            *   public java.lang.String com.qm.test.Student.name
            *   protected java.lang.String com.qm.test.Student.address
            */
    }
    }

                                                                                      获取类中的方法

    public class Test{
        
           public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
         //获取方法的关键代码
    
            Class c=Student.class;
    		Method[] ms=c.getMethods();
    		for (Method method : ms) {
    			System.out.println(method);
    		}
    
        //此段代码将会输出Student类中继承了Object类的一些方法
    
    }
    }

     

    展开全文
  • 用最直接的大白话来聊一聊Java中的反射机制

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

    视频功能审核通过了,可以看视频啦!

    建议花十几分钟的时间把视频看完,然后再结合博客里的内容来理解,相信对你了解Java中的反射会有所帮助

    记得点关注啊

    用最通俗易懂的话来说一说Java中的反射机制

    思考:在讲反射之前,先思考一个问题,java中如何创建一个对象,有哪几种方式?

    Java中创建对象大概有这几种方式:

    1、使用new关键字:这是我们最常见的也是最简单的创建对象的方式

    2、使用Clone的方法:无论何时我们调用一个对象的clone方法,JVM就会创建一个新的对象,将前面的对象的内容全部拷贝进去

    3、使用反序列化:当我们序列化和反序列化一个对象,JVM会给我们创建一个单独的对象

    上边是Java中常见的创建对象的三种方式,其实除了上边的三种还有另外一种方式,就是接下来我们要讨论的 “反射”

    1、反射概述

    1.1什么是反射

    反射就是把Java类中的各个部分,映射成一个个的Java对象,拿到这些对象后可以做一些事情。

    既然说反射是反射Java类中的各个组成部分,所以说咱们得知道一个类中有哪儿些部分?

    例如,一个类有:成员变量,方法,构造方法,等信息,利用反射技术咱们可以把这些组成部分映射成一个个对象。

    1.2、反射能干什么

    说完反射的概念后,咱们说一下反射能干什么?

    一般来说反射是用来做框架的,或者说可以做一些抽象度比较高的底层代码,反射在日常的开发中用到的不多,但是咱们还必须搞懂它,因为搞懂了反射以后,可以帮助咱们理解框架的一些原理。所以说有一句很经典的话:反射是框架设计的灵魂。现在说完这个可能还不太能理解,不急,等下说完一个快速入门的例子后,应该会稍微有点感觉

    1.3、怎么得到想反射的类

    刚才已经说过,反射是对一个类进行解剖,想解剖一个东西,前提是首先你得拿到这个东西,那么怎么得到咱们想解剖的类呢?

    首先大家要明白一点,咱们写的代码是存储在后缀名是 .java的文件里的,但是它会被编译,最终真正去执行的是编译后的 .class文件。Java是面向对象的语言,一切皆对象,所以java认为 这些编译后的 class文件,这种事物也是一种对象,它也给抽象成了一种类,这个类就是Class,大家可以去AIP里看一下这个类

    所以拿到这个类后,就相当于拿到了咱们想解剖的类,那怎么拿到这个类?

    看API文档后,有一个方法forName(String className); 而且是一个静态的方法,这样咱们就可以得到想反射的类了

    到这里,看Class clazz = Class.forName("com.cj.test.Person");这个应该有点感觉了吧

    Class.forName("com.cj.test.Person");因为这个方法里接收的是个字符串,字符串的话,我们就可以写在配置文件里,然后利用反射生成我们需要的对象,这才是我们想要的。很多框架里都有类似的配置

    2、解剖类

    我们知道一个类里一般有构造函数、方法、成员变量(字段/属性)这三部分组成

    翻阅API文档,可以看到

    Class对象提供了如下常用方法:

    public Constructor getConstructor(Class<?>…parameterTypes)

    public Method getMethod(String name,Class<?>… parameterTypes)

    public Field getField(String name)

    public Constructor getDeclaredConstructor(Class<?>…parameterTypes)

    public Method getDeclaredMethod(String name,Class<?>… parameterTypes)

    public Field getDeclaredField(String name)

    这些方法分别用于帮咱们从类中解剖出构造函数、方法和成员变量(属性)。

    然后把解剖出来的部分,分别用Constructor、Method、Field对象表示。

    2.1反射构造方法

    2.1.1反射无参的构造函数

    可以看到 默认的无参构造方法执行了

    从上边的例子看出,要想反射,首先第一步就是得到类的字节码

    所以简单说一下得到类的字节码的几种方式

    (1)、Class.forName("com.cj.test.Person"); 这就是上边我们用的方式

    (2)、对象.getClass();

    (3)、类名.class;

    2.1.2反射“一个参数”的构造函数

    2.1.3反射“多个参数”的构造函数

    2.1.4反射“私有”的构造函数

    注意:在反射私有的构造函数时,用普通的clazz.getConstructor()会报错,因为它是私有的,所以提供了专门反射私有构造函数的方法 clazz.getDeclaredConstructor(int.class);//读取私有的构造函数,用这个方法读取完还需要设置一下暴力反射才可以

    c.setAccessible(true);//暴力反射

    2.1.5反射得到类中所有的构造函数

     

    2.2反射类中的方法

    package com.cj.test;
    
    import java.util.Date;
    
    public class Person {
    	
    	public Person(){
    		System.out.println("默认的无参构造方法执行了");
    	}
    
    	public Person(String name){
    		System.out.println("姓名:"+name);
    	}
    	
    	public Person(String name,int age){
    		System.out.println(name+"="+age);
    	}
    	
    	private Person(int age){
    		System.out.println("年龄:"+age);
    	}
    	
    	public void m1() {
    		System.out.println("m1");
    	}
    	
    	public void m2(String name) {
    		System.out.println(name);
    	}
    	
    	public String m3(String name,int age) {
    		System.out.println(name+":"+age);
    		return "aaa";
    	}
    	
    	private void m4(Date d) {
    		System.out.println(d);
    	}
    	
    	public static void m5() {
    		System.out.println("m5");
    	}
    	
    	public static void m6(String[] strs) {
    		System.out.println(strs.length);
    	}
    
            public static void main(String[] args) {
    		System.out.println("main");
    	}
    
    }
    
    
    
    
    
    package com.cj.test;
    
    import java.lang.reflect.Method;
    import java.util.Date;
    import org.junit.Test;
    
    public class Demo2 {
    
    	@Test//public void m1()
    	public void test1() throws Exception{
    		Class clazz = Class.forName("com.cj.test.Person");
    		Person p = (Person)clazz.newInstance();
    		Method m = clazz.getMethod("m1", null);
    		m.invoke(p, null);
    	}
    	@Test//public void m2(String name)
    	public void test2() throws Exception{
    		Class clazz = Person.class;
    		Person p = (Person) clazz.newInstance();
    		Method m = clazz.getMethod("m2", String.class);
    		m.invoke(p, "张三");
    	}
    	@Test//public String m3(String name,int age)
    	public void test3() throws Exception{
    		Class clazz = Person.class;
    		Person p = (Person) clazz.newInstance();
    		Method m = clazz.getMethod("m3", String.class,int.class);
    		String returnValue = (String)m.invoke(p, "张三",23);
    		System.out.println(returnValue);
    	}
    	@Test//private void m4(Date d)
    	public void test4() throws Exception{
    		Class clazz = Person.class;
    		Person p = (Person) clazz.newInstance();
    		Method m = clazz.getDeclaredMethod("m4", Date.class);
    		m.setAccessible(true);
    		m.invoke(p,new Date());
    	}
    	@Test//public static void m5()
    	public void test5() throws Exception{
    		Class clazz = Person.class;
    		Method m = clazz.getMethod("m5", null);
    		m.invoke(null,null);
    	}
    	@Test//private static void m6(String[] strs)
    	public void test6() throws Exception{
    		Class clazz = Person.class;
    		Method m = clazz.getDeclaredMethod("m6",String[].class);
    		m.setAccessible(true);
    		m.invoke(null,(Object)new String[]{"a","b"});
    	}
    	@Test
    	public void test7() throws Exception{
    		Class clazz = Person.class;
    		Method m = clazz.getMethod("main",String[].class);
    		m.invoke(null,new Object[]{new String[]{"a","b"}});
    	}
    }
    

    *****注意:看下上边代码里test6和test7的invoke方法里传的参数和其他的有点不一样

    这是因为 jdk1.4和jdk1.5处理invoke方法有区别

    1.5:public Object invoke(Object obj,Object…args)

    1.4:public Object invoke(Object obj,Object[] args)

    由于JDK1.4和1.5对invoke方法的处理有区别, 所以在反射类似于main(String[] args) 这种参数是数组的方法时需要特殊处理

    启动Java程序的main方法的参数是一个字符串数组,即public static void main(String[] args),通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组是一个参数,而按jdk1.4的语法,数组中的每个元素对应一个参数,当把一个字符串数组作为参数传递给invoke方法时,javac会到底按照哪种语法进行处理呢?jdk1.5肯定要兼容jdk1.4的语法,会按jdk1.4的语法进行处理,即把数组打散成为若干个单独的参数。所以,在给main方法传递参数时,不能使用代码mainMethod.invoke(null,new String[]{“xxx”}),javac只把它当作jdk1.4的语法进行理解,而不把它当作jdk1.5的语法解释,因此会出现参数个数不对的问题。

    上述问题的解决方法:

    (1)mainMethod.invoke(null,new Object[]{new String[]{"xxx"}});

    这种方式,由于你传的是一个数组的参数,所以为了向下兼容1.4的语法,javac遇到数组会给你拆开成多个参数,但是由于咱们这个Object[ ] 数组里只有一个元素值,所以就算它拆也没关系

    (2)mainMethod.invoke(null,(Object)new String[]{"xxx"});

    这种方式相当于你传的参数是一个对象,而不是数组,所以就算是按照1.4的语法它也不会拆,所以问题搞定

    编译器会作特殊处理,编译时不把参数当作数组看待,也就不会数组打散成若干个参数了

    对上边的描述进行一下总结:在反射方法时,如果方法的参数是一个数组,考虑到向下兼容问题,会按照JDK1.4的语法来对待(JVM会把传递的数组参数拆开,拆开就会报参数的个数不匹配的错误)
    解决办法:防止JVM拆开你的数组
        方式一:把数组看做是一个Object对象
        方式二:重新构建一个Object数组,那个参数数组作为唯一的元素存在。

    2.3反射类中的属性字段

    package com.cj.test;
    
    import java.util.Date;
    
    public class Person {
    	
    	public String name="李四";
    	private int age = 18;
    	public static Date time;
    	
    	public int getAge() {
    		return age;
    	}
    	
    	public Person(){
    		System.out.println("默认的无参构造方法执行了");
    	}
    
    	public Person(String name){
    		System.out.println("姓名:"+name);
    	}
    	
    	public Person(String name,int age){
    		System.out.println(name+"="+age);
    	}
    	
    	private Person(int age){
    		System.out.println("年龄:"+age);
    	}
    	
    	public void m1() {
    		System.out.println("m1");
    	}
    	
    	public void m2(String name) {
    		System.out.println(name);
    	}
    	
    	public String m3(String name,int age) {
    		System.out.println(name+":"+age);
    		return "aaa";
    	}
    	
    	private void m4(Date d) {
    		System.out.println(d);
    	}
    	
    	public static void m5() {
    		System.out.println("m5");
    	}
    	
    	public static void m6(String[] strs) {
    		System.out.println(strs.length);
    	}
    	
    	public static void main(String[] args) {
    		System.out.println("main");
    	}
    	
    }
    
    
    
    
    
    package com.cj.test;
    
    import java.lang.reflect.Field;
    import java.util.Date;
    import org.junit.Test;
    
    public class Demo3 {
    	//public String name="李四";
    	@Test
    	public void test1() throws Exception{
    		Class clazz = Person.class;
    		Person p = (Person)clazz.newInstance();
    		Field f = clazz.getField("name");
    		String s = (String)f.get(p);
    		System.out.println(s);
    		
    		//更改name的值
    		f.set(p, "王六");
    		System.out.println(p.name);
    	}
    	@Test//private int age = 18;
    	public void test2() throws Exception{
    		Class clazz = Person.class;
    		Person p = (Person)clazz.newInstance();
    		Field f = clazz.getDeclaredField("age");
    		f.setAccessible(true);
    		int age = (Integer)f.get(p);
    		System.out.println(age);
    		
    		f.set(p, 28);
    		age = (Integer)f.get(p);
    		System.out.println(age);
    	}
    	@Test//public static Date time;
    	public void test3() throws Exception{
    		Class clazz = Person.class;
    		Field f = clazz.getField("time");
    		f.set(null, new Date());
    		System.out.println(Person.time);
    	}
    }
    

    以上就是自己对Java中反射的一些学习总结,欢迎大家留言一起学习、讨论

    看完上边有关反射的东西, 对常用框架里的配置文件是不是有点思路了

    上边是Spring配置文件里的常见的bean配置,这看起来是不是可以用反射很轻易的就可以实现:解析xml然后把xml里的内容作为参数,利用反射创建对象。

    除了这个,常用的框架里还有很多地方都用到了反射,反射是框架的灵魂,具备反射知识和思想,是看懂框架的基础

    平常用到的框架,除了配置文件的形式,现在很多都使用了注解的形式,其实注解也和反射息息相关,使用反射也能轻而易举的拿到类、字段、方法上的注解,然后编写注解解析器对这些注解进行解析,做一些相关的处理,所以说不管是配置文件还是注解的形式,它们都和反射有关

    感兴趣的话可以看下这篇,这篇里边包含了XML解析、反射的东西,模拟了一个Struts2的核心代码

    利用Java反射模拟一个Struts2框架 Struts2主要核心设计 手动实现Struts2核心代码

    跟反射相关的还有内省、自定义注解,最近也抽时间大概整理了一下

    Java反射——内省(Introspector)以及BeanUtils内省框架

    Java中的注解以及自定义注解

    感兴趣的小可爱可以了解一下~

    觉得对你有帮助的话,可以点个关注,点个赞,3Q~

     

    展开全文
  • Java 反射机制

    万次阅读 多人点赞 2018-08-15 16:43:11
    Java 反射机制是在运行状态中,对于任意一个类,都能够获得这个类的所有属性和方法,对于任意一个对象都能够调用它的任意一个属性和方法。这种在运行时动态的获取信息以及动态调用对象的方法的功能称为Java反射...

    一、反射机制概述

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

    Class 类与 java.lang.reflect 类库一起对反射的概念进行了支持,该类库包含了 Field,Method,Constructor 类 (每个类都实现了 Member 接口)。这些类型的对象时由 JVM 在运行时创建的,用以表示未知类里对应的成员。

    这样你就可以使用 Constructor 创建新的对象,用 get() 和 set() 方法读取和修改与 Field 对象关联的字段,用 invoke() 方法调用与 Method 对象关联的方法。另外,还可以调用 getFields() getMethods() 和 getConstructors() 等很便利的方法,以返回表示字段,方法,以及构造器的对象的数组。这样匿名对象的信息就能在运行时被完全确定下来,而在编译时不需要知道任何事情。

    二、获取字节码的方式

    在 Java 中可以通过三种方法获取类的字节码 (Class) 对象

    • 通过 Object 类中的 getClass() 方法,想要用这种方法必须要明确具体的类并且创建该类的对象。
    • 所有数据类型都具备一个静态的属性.class 来获取对应的 Class 对象。但是还是要明确到类,然后才能调用类中的静态成员。
    • 只要通过给定类的字符串名称就可以获取该类的字节码对象,这样做扩展性更强。通过 Class.forName() 方法完成,必须要指定类的全限定名,由于前两种方法都是在知道该类的情况下获取该类的字节码对象,因此不会有异常,但是 Class.forName() 方法如果写错类的路径会报 ClassNotFoundException 的异常。
    package com.jas.reflect;
    
    public class ReflectTest {
        public static void main(String[] args) {
    
            Fruit fruit = new Fruit();
            Class<?> class1 = fruit.getClass();     //方法一
    
            Class<?> class2 = Fruit.class;     //方法二
    
            Class class3 = null;     
            try {    //方法三,如果这里不指定类所在的包名会报 ClassNotFoundException 异常
                class3 = Class.forName("com.jas.reflect.Fruit");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
    
            System.out.println(class1 + "  " +class2 + "    " + class3);
    
        }
    }
    
    class Fruit{}
    

    三、通过反射机制获取类信息

    通过反射机制创建对象,在创建对象之前要获得对象的构造函数对象,通过构造函数对象创建对应类的实例。

    下面这段代码分别在运行期间创建了一个无参与有参的对象实例。由于 getConstructor() 方法与 newInstance() 方法抛出了很多异常 (你可以通过源代码查看它们),这里就简写了直接抛出一个 Exception,下同。

    package com.jas.reflect;
    
    import java.lang.reflect.Constructor;
    
    public class ReflectTest {
        public static void main(String[] args) throws Exception {
    
            Class clazz = null;
            clazz = Class.forName("com.jas.reflect.Fruit");
            Constructor<Fruit> constructor1 = clazz.getConstructor();
            Constructor<Fruit> constructor2 = clazz.getConstructor(String.class);
    
            Fruit fruit1 = constructor1.newInstance();
            Fruit fruit2 = constructor2.newInstance("Apple");
    
        }
    }
    
    class Fruit{
        public Fruit(){
            System.out.println("无参构造器 Run...........");
        }
        public Fruit(String type){
            System.out.println("有参构造器 Run..........." + type);
        }
    
    }
    

    输出:
    无参构造器 Run………..
    有参构造器 Run………..Apple

    通过反射机制获取 Class 中的属性。

    package com.jas.reflect;
    
    import java.lang.reflect.Field;
    
    public class ReflectTest {
        public static void main(String[] args) throws Exception {
    
            Class<?> clazz = null;
            Field field = null;
    
            clazz = Class.forName("com.jas.reflect.Fruit");
            //field = clazz.getField("num");       getField() 方法不能获取私有的属性
            // field = clazz.getField("type");     访问私有字段时会报 NoSuchFieldException 异常
            field = clazz.getDeclaredField("type");     //获取私有 type 属性
            field.setAccessible(true);  //对私有字段的访问取消检查
            Fruit fruit = (Fruit) clazz.newInstance();  //创建无参对象实例
            field.set(fruit,"Apple");   //为无参对象实例属性赋值
            Object type = field.get(fruit); //通过 fruit 对象获取属性值
    
            System.out.println(type);
        }
    }
    
    class Fruit{
        public int num;
        private String type;
    
        public Fruit(){
            System.out.println("无参构造器 Run...........");
        }
        public Fruit(String type){
            System.out.println("有参构造器 Run..........." + type);
        }
    
    }

    输出:
    无参构造器 Run………..
    Apple

    通过反射机制获取 Class 中的方法并运行。

    package com.jas.reflect;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Method;
    
    public class ReflectTest {
        public static void main(String[] args) throws Exception {
    
            Class clazz = null;
            Method method = null;
    
            clazz = Class.forName("com.jas.reflect.Fruit");
            Constructor<Fruit> fruitConstructor = clazz.getConstructor(String.class);
            Fruit fruit = fruitConstructor.newInstance("Apple");    //创建有参对象实例
    
            method = clazz.getMethod("show",null);  //获取空参数 show 方法
            method.invoke(fruit,null);  //执行无参方法
    
            method = clazz.getMethod("show",int.class); //获取有参 show 方法
            method.invoke(fruit,20);  //执行有参方法
    
        }
    }
    
    class Fruit{
        private String type;
    
        public Fruit(String type){
            this.type = type;
        }
        public void show(){
            System.out.println("Fruit type = " + type);
        }
        public void show(int num){
            System.out.println("Fruit type = " + type + ".....Fruit num = " + num);
        }
    }

    输出:
    Fruit type = Apple
    Fruit type = Apple…..Fruit num = 20

    四、反射机制简单应用(使用简单工厂创建对象)

    Class.forName() 生成的结果是在编译时不可知的,因此所有的方法特征签名信息都是在执行时被提取出来的。反射机制能过创建一个在编译期完全未知的对象,并调用该对象的方法。

    以下是反射机制与泛型的一个应用,通过一个工厂类创建不同类型的实例。

    要创建对象的实例类 Apple :

    package com.jas.reflect;
    
    public interface Fruit {}
    class Apple implements Fruit{}
    

    加载的配置文件 config.properties:

     Fruit=com.jas.reflect.Apple

    工厂类 BasicFactory :

    package com.jas.reflect;
    
    import java.io.FileReader;
    import java.util.Properties;
    
    public class BasicFactory {
        private BasicFactory(){}
    
        private static BasicFactory bf = new BasicFactory();
        private static Properties pro = null;
    
        static{
            pro = new Properties();
            try{    
                //通过类加载器加载配置文件
                pro.load(new FileReader(BasicFactory.class.getClassLoader().
                        getResource("config.properties").getPath()));
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static BasicFactory getFactory(){
            return bf;
        }
    
        //使用泛型获得通用的对象
        public  <T> T newInstance(Class<T> clazz){
            String cName = clazz.getSimpleName();   //获得字节码对象的类名
            String clmplName = pro.getProperty(cName);   //根据字节码对象的类名通过配置文件获得类的全限定名
    
            try{
                return (T)Class.forName(clmplName).newInstance();   //根据类的全限定名创建实例对象
            }catch (Exception e) {
                throw new RuntimeException(e);
            }
    
        }
    }
    

    创建对象实例:

    package com.jas.reflect;
    
    public class ReflectTest {
        public static void main(String[] args) throws Exception {
            Fruit fruit = BasicFactory.getFactory().newInstance(Fruit.class);
            System.out.println(fruit);
        }
    }

    输出
    com.jas.reflect.Apple@4554617c

    上面这个实例通过一个工厂创建不同对象的实例,通过这种方式可以降低代码的耦合度,代码得到了很大程度的扩展,以前要创建 Apple 对象需要通过 new 关键字创建 Apple 对象,如果我们也要创建 Orange 对象呢?是不是也要通过 new 关键字创建实例并向上转型为 Fruit ,这样做是麻烦的。

    现在我们直接有一个工厂,你只要在配置文件中配置你要创建对象的信息,你就可以创建任何类型你想要的对象,是不是简单很多了呢?可见反射机制的价值是很惊人的。

    Spring 中的 IOC 的底层实现原理就是反射机制,Spring 的容器会帮我们创建实例,该容器中使用的方法就是反射,通过解析 xml 文件,获取到 id 属性和 class 属性里面的内容,利用反射原理创建配置文件里类的实例对象,存入到 Spring 的 bean 容器中。

      参考书籍:
     《Java 编程思想》 Bruce Eckel 著 陈昊鹏 译

    展开全文
  • java反射原理-重要

    万次阅读 多人点赞 2018-11-21 11:23:54
    1,JAVA反射机制是在运行状态中 对于任意一个类,都能够知道这个类的所有属性和方法; 对于任意一个对象,都能够调用它的任意一个方法和属性; 这种动态获取的信息以及动态调用对象的方法的功能称为java语言的...

    一,反射是什么(反射是框架设计的灵魂)

    1,JAVA反射机制是在运行状态中

    对于任意一个类,都能够知道这个类的所有属性和方法;

    对于任意一个对象,都能够调用它的任意一个方法和属性;

    这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

    2,反射提供的功能:

    • 在运行时判断任意一个对象所属的类
    • 在运行时构造任意一个类的对象
    • 在运行时判断任意一个类所具有的成员变量和方法
    • 在运行时调用任意一个对象的方法

    要想解剖一个类,必须先要获取到该类的字节码文件对象(class)。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

    3,关于class对象和这个class类

    • Class对象的由来是将class文件读入内存,并为之创建一个Class对象

    4,class类 :代表一个类,是Java反射机制的起源和入口

    • 用于获取与类相关的各种信息, 提供了获取类信息的相关方法
    • Class类继承自Object类

    • Class类是所有类的共同的图纸

    • 每个类有自己的对象,同时每个类也看做是一个对象,有共同的图纸Class,存放类的结构信息,能够通过相应方法取出相应的信息:类的名字、属性、方法、构造方法、父类和接口。

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

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


    原文:https://blog.csdn.net/sinat_38259539/article/details/71799078

    5,反射的使用场景

    •     Java编码时知道类和对象的具体信息,此时直接对类和对象进行操作即可,无需反射
    •     如果编码时不知道类或者对象的具体信息,此时应该使用反射来实现

                比如类的名称放在XML文件中,属性和属性值放在XML文件中,需要在运行时读取XML文件,动态获取类的信息
                在编译时根本无法知道该对象或类可能属于哪些类,程序只依靠运行时信息来发现该对象和类的真实信息
     

    二,获取反射入口(class对象)的三种方法

    要想操作反射,必须先拿到反射的入口

    1,通过通过Class.forName("全类名")

    try {
    			Class<?> perClazz = Class.forName("reflect_fanshe.Person");
    			System.out.println(perClazz);
    		} catch (ClassNotFoundException e) {
    			
    			e.printStackTrace();
    		}

    2,类名.class

    Class<?> perClazz2 = Person.class;

    3,对象.getClass()

    Person person = new Person();
    Class<?> perClazz3 = person.getClass();

    三,根据反射入口对象(class)获取类的各种信息

    可以用一个类的反射入口class对象获取类的所有信息

    • 例1:perClazz.getMethods()  获取此类的所有public方法(父类的,实现接口的,自己的)
    Class<?> perClazz = null;
    		try {
    			perClazz = Class.forName("reflect_fanshe.Person");
    		} catch (ClassNotFoundException e) {
    			
    			e.printStackTrace();
    		}
    		Method[] methods = perClazz.getMethods();
                    //遍历所有方法
    		for (Method method : methods) {
    			System.out.println(method);
    		}
    	}
    • 例2:获取所有的构造方法

    • 例3: 获取父类

    •  例4:获取当前类(只有本类的)的所有方法和属性,包括私有的

     

    •  重要:可以获取当前类的对象,并通过对象调用类的方法

    四,通过反射获取对象的实例,并操作对象

    1,class.newInstance() ,并强转类型,然后就可以操作对象了,主要是调用方法。

    2,操作属性,可以操作类里面的public属性和private属性

    如果属性是private,正常情况下是不允许外界操作属性值,这里可以用Field类的setAccessible(true)方法,暂时打开操作的权限

    调用方法也一样,可以调用私有的方法,null是因为这个方法没有参数

    五,在 程序执行中,动态的决定调用的类,以及方法

    在本例中,程序执行之前,程序根本不知道具体的类和方法名是什么,需要执行时解析properties文件,但是反射就可以办到。

    配置文件:

     

    反射机制:

    展开全文
  • JAVA中的反射机制

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

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

    万次阅读 2020-02-24 18:44:35
    编译期和运行期,编译期就是编译器帮你把源代码翻译成机器能识别的代码,比如编译器把java代码编译成jvm识别的字节码文件,而运行期指的是将可执行文件交给操作系统去执行,JAVA反射机制是在运行状态中,对于任意一...
  • 转载需注明出处:java反射机制(1)- 知识点总结Java Reflection API操作1 什么是反射机制  什么是反射机制?简单点说就是程序在运行时能够获取自身的信息。在java中,只要给定类的全名,就可以通过反射机制来获取...
  • Java反射机制---面试

    千次阅读 2018-10-09 18:02:05
     什么是反射机制反射机制的作用是什么 【答案】 反射是为了能够动态地加载一个类,动态地调用一个方法,动态地访问一个属性等动态要求而设计的。它的出发点就在于JVM会为每个类创建一个java.lang.Class类的...
  • java获取反射机制的三种方式

    千次阅读 2018-05-27 19:57:17
    java 获取反射常使用的三种方式:1.通过new对象实现反射机制2.通过路径实现反射机制3.通过类名实现反射机制例子:建立一个学生类:public class Student { private int id; String name; protected boolean sex; ...
  • java面试题--java反射机制

    万次阅读 2015-04-10 15:04:50
    Java反射机制的作用: 1)在运行时判断任意一个对象所属的类。 2)在运行时判断任意一个类所具有的成员变量和方法。 3)在运行时任意调用一个对象的方法 4)在运行时构造任意一个类的对象 拓展: 1、什么...
  • Java通过反射机制调用某个类的方法

    万次阅读 2018-06-02 10:53:24
    通过反射机制调用类的方法,主要用到下面的方法: public Object invoke(Object obj, Object... args) 参数: obj是调用基础方法的实例对象 调用基础方法索要传递的参数,参数是一个变长类型 下面是一个具体...
  • 深入浅出学习hibernate框架(三):java反射机制

    万次阅读 多人点赞 2013-05-28 19:58:48
    上篇博客写到了JDBC的基本操作,今天准备写一篇关于JAVA反射机制的文章,因为java的反射机制和上一篇JDBC都是Hibernate框架的基本要素。在Hibernate的运行机制中,这两块的内容正好是用来处理对象关系映射,所以这两...
  • 反射机制及反射原理

    千次阅读 2018-04-25 19:32:36
    反射机制:Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的...
  • java反射机制的作用与优点

    千次阅读 2017-09-06 17:15:09
    java反射机制就是增加程序的灵活性,避免将程序写死到代码里, 例如: 实例化一个 person()对象, 不使用反射, new person(); 如果想变成 实例化 其他类, 那么必须修改源代码,并重新编译。 使用反射: class....
  • 浅析Java中的反射机制原理

    万次阅读 多人点赞 2015-11-20 15:24:21
     Java反射机制使用的还是比较广泛的,系统的灵活性、可扩展性大都都是通过反射等方式来加载外部插件,使得系统与插件解耦的同时,增加了功能。但是很多人都只是会用,却是不知道它的实现机制,今天就由我来带大家...
  • )先来一段百度百科的关于反射的定义:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的...
  • Java 反射 面试题

    万次阅读 2018-11-26 21:02:57
    1)Java反射机制的作用 1. 在运行时判断任意一个对象所属的类 2. 在运行时构造任意一个类的对象 3. 在运行时判断任意一个类所具有的成员变量和方法 4. 在运行时调用任意一个对象的方法 2)什么是反射机制? 简单说,...
  • Java反射机制的适用场景及其利与弊

    万次阅读 多人点赞 2014-06-08 16:13:28
    Java反射机制的适用场景及其利与弊   一、反射的适用场景是什么? 1).Java的反射机制在做基础框架的时候非常有用,有一句话这么说来着:反射机制是很多Java框架的基石。而一般应用层面很少用,不过这种东西,...
  • Java反射常见面试题

    万次阅读 2019-09-29 13:41:12
    这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语言的反射机制。 2. 哪里用到反射机制? JDBC中,利用反射动态加载了数据库驱动程序。 Web服务器中利用反射调用了Sevlet的服务方法。 Eclispe等开发...
1 2 3 4 5 ... 20
收藏数 153,535
精华内容 61,414
关键字:

java反射机制