Java反射机制详解一

1反射机制是什么

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

在面向对象的世界里,万事万物皆对象.在java语言里,静态的成员,普通数据类型是不是对象呢?

类又是谁的对象呢?

首先类是对象,类是java.lang.Class类的实例对象.

新创建一个Foo类

Foo这个类也是一个实例对象,是Class类的实例对象,这个对象在官网被称为(class type).

反射是java程序开发语言的特性之一,它允许运行中的java程序获取自身的信息,并且可以操作类或者对象内部的属性.

反射的核心是JVM在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。

了解反射其实需要了解JVM,不过一般的资料不会在这一部分讲到JVM,毕竟学习也是要从浅入深的.

2反射机制能做什么


反射机制主要提供了以下功能:

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

注意;是运行时获取而不是编译时获取.其实很多时候我们直接用eclipse写代码忽略了编译的过程

在Eclipse,当我们输入一个点的时候(比如 a.)   编译器就会自动列出它的属性和方法,这里就会用到反射

3反射机制的相关API (在这里只说反射机制五种功能的前两种)

java的反射机制的实现要借助于4个类: class,Constructor,Field,Method;

通过一个对象获得完整的包名和类名

package cn.xins08.boke;

public class TestReflect {

    public static void main(String[] args) {
        TestReflect testReflect = new TestReflect();
        System.out.println(testReflect.getClass().getName());
        // 结果:cn.xins08.boke.TestReflect

    }

}

实例化Class对象:

实现反射机制获取类有三种方法:

package cn.xins08.boke;

public class TestReflect {
    public static void main(String[] args) throws Exception {

        Class<?> class1 = null;
        Class<?> class2 = null;
        Class<?> class3 = null;
        //第一种方式(在JDBC开发中常用此方法加载数据驱动)
        class1 = Class.forName("cn.xins08.boke.TestReflect");
      //第三种方式:java中任何一个对象都有getClass方法
        class2 = new TestReflect().getClass();
        
        //第三种方式java中任何一个对象都有class属性
        class3 = TestReflect.class;
        System.out.println("类名称: " + class1.getName());
        System.out.println("类名称: " + class2.getName());
        System.out.println("类名称: " + class3.getName());
        // 打印结果:
        /*
         * 类名称: cn.xins08.boke.TestReflect 类名称: cn.xins08.boke.TestReflect 类名称:
         * cn.xins08.boke.TestReflect
         */
    }
}

获取一个对象的父类与实现的接口:

package cn.xins08.boke;

import java.io.Serializable;

public class TestReflect implements Serializable {
     private static final long serialVersionUID = -2862585049955236662L;
    public static void main(String[] args) throws Exception {
         
            
                Class<?> clazz = Class.forName("cn.xins08.boke.TestReflect");
                // 取得父类
                Class<?> parentClass = clazz.getSuperclass();
                System.out.println("clazz的父类为:" + parentClass.getName());
                // clazz的父类为: java.lang.Object
                // 获取所有的接口
                Class<?> intes[] = clazz.getInterfaces();
                System.out.println("clazz实现的接口有:");
                for (int i = 0; i < intes.length; i++) {
                    System.out.println((i + 1) + ":" + intes[i].getName());
                }
                // clazz实现的接口有:
                // 1:java.io.Serializable
        
    }
}

创建实例:

通过反射来生成对象主要有两种方式:

(1)使用Class对象的newInstance()方法来创建Class对象对应类的实例。

Class<?> c = String.class;
Object str = c.newInstance();

初始化一个类,生成一个实例的时候,new与newInstance() 有什么区别?

区别在于创建对象的方式不一样,前者是使用类加载机制,那么为什么会有两种创建对象方式?这个就要从可伸缩、可扩展,可重用等软件思想上解释了。

newInstance: 弱类型。低效率。只能调用无参构造。
new: 强类型。相对高效。能调用任何public构造。
newInstance()是实现IOC、反射、面对接口编程 和 依赖倒置 等技术方法的必然选择,new 只能实现具体类的实例化,不适合于接口编程。

(2)先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建实例。这种方法可以用指定的构造器构造类的实例。

// 获取String所对应的Class对象
        Class<?> c = String.class;
        // 获取String类带一个String参数的构造器
        Constructor constructor = c.getConstructor(String.class);
        // 根据构造器创建实例
        Object obj = constructor.newInstance("23333");
        System.out.println(obj);

注意事项:反射会额外的消耗一定的系统资源,如果不需要动态的创建一个对象,那么就不需要用反射

在文章的最后我们讨论下工厂模式:

package cn.xins08.boke;

public interface Fruit {
public void eat();

}
package cn.xins08.boke;

public class Apple implements Fruit{
    public void eat(){
        System.out.println("吃苹果");
    }

    

}
package cn.xins08.boke;

public class Factory {
public static Fruit getInstance(String className){
    if("apple".equals(className)){
        return new Apple();
    }
    return null;
}
}
package cn.xins08.boke;

public class FactoryDemo {

    public static void main(String[] args) {
        Fruit f = Factory.getInstance("apple");
        f.eat();

    }

}
//返回的结果是"吃苹果"

这种是一个最简单的工厂设计模式,但是有一个很大的问题是,如果现在接口的子类增加了,那么工厂类肯定需要改.而造成这个问题的病因就是new,如果变成反射机制就不一样了.反射的实例化对象只需要包.类就可以了.

package cn.xins08.boke;

public interface Fruit {
public void eat();

}
package cn.xins08.boke;

public class Orange implements Fruit{
    public void eat(){
        System.out.println("吃橘子");
    }

    

}
package cn.xins08.boke;

public class Apple implements Fruit{
    public void eat(){
        System.out.println("吃苹果");
    }

    }
package cn.xins08.boke;

public class Factory {
public static Fruit getInstance(String className){
   Fruit fruit = null;
try{
   //这里是Fruit的类类型,做强制类型转换 
    fruit = (Fruit) Class.forName(className).newInstance() ;
    } catch(Exception e) {
       e.printStackTrace();
   }
       return  f ;
       }
  }

}
package cn.xins08.boke;

public class FactoryDemo {

    public static void main(String[] args) {
        Fruit f = Factory.getInstance("cn.xins08.boke.Apple");
        f.eat();

    }

}

这时候我们发现即使增加几个接口的子类,工厂类照样可以完成对象的实例化操作,可以对应所有的变化.

到目前为止你已经会了最基本的反射使用了,在学习Spring之前先讲这些,等学习了Spring的依赖注入,反转控制之后,相信会对反射有更好的理解.

关于反射以下功能,等写完后会在本文加链接

  • 在运行时判断任意一个类所具有的成员变量和方法;
  • 在运行时调用任意一个对象的方法;
  • 生成动态代理。

--java一万小时成神之路--本文首发与51CTO博客---

近期读书计划:

《思考,快与慢》

《浪潮之巅》

时间: 2024-08-24 11:42:42

Java反射机制详解一的相关文章

Java反射机制详解

Java反射机制详解 Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制. 1.关于Class 1.Class是一个类,一个描述类的类(也就是描述类本身),封装了描述方法的Method,描述字段的Filed,描述构造器的Constructor等属性    2.对象照镜子后(反射)可以得到的信息:某个类的数据成员名.方法和构造器.某个类到底实现

Java 反射机制详解(下)

续:Java 反射机制详解(上) 三.怎么使用反射 想要使用反射机制,就必须要先获取到该类的字节码文件对象(.class),通过字节码文件对象,就能够通过该类中的方法获取到我们想要的所有信息(方法,属性,类名,父类名,实现的所有接口等等),每一个类对应着一个字节码文件也就对应着一个Class类型的对象,也就是字节码文件对象. 获取字节码文件对象的三种方式.  1.Class class1= Class.forName("全限定类名"); //通过Class类中的静态方法forName,

【转载】Java反射机制详解

转自:http://baike.xsoftlab.net/view/209.html#3_8 1反射机制是什么 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 2反射机制能做什么 反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类: 在运行时构造任意一个类的对象: 在运行时判断任意一个类所具有的成员变量和方法: 在运行时调用任意一个

java反射机制详解 及 Method.invoke解释 getMethod

JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制.Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类:在运行时构造任意一个类的对象:在运行时判断任意一个类所具有的成员变量和方法:在运行时调用任意一个对象的方法:生成动态代理.1. 得到某个对象的属性 public Object getProperty(Obje

java反射机制详解 及 Method.invoke解释

JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制.Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类:在运行时构造任意一个类的对象:在运行时判断任意一个类所具有的成员变量和方法:在运行时调用任意一个对象的方法:生成动态代理.1. 得到某个对象的属性 Java代码   public Object getProp

Java反射机制详解(3) -java的反射和代理实现IOC模式 模拟spring

IOC(Inverse of Control) 可翻译为“控制反转”,但大多数人都习惯将它称为“依赖注入”.在Spring中,通过IOC可以将实现类.参数信息等配置在其对应的配置文件中,那么当 需要更改实现类或参数信息时,只需要修改配置文件即可,这种方法在上例的基础上更进一步的降低了类与类之间的耦合.我们还可以对某对象所需要的其它对象进 行注入,这种注入都是在配置文件中做的,Spring的IOC的实现原理利用的就是Java的反射机制, Spring还充当了工厂的角色,我们不需要自己建立工厂类.S

Java反射机制详解(1) -反射定义

---恢复内容开始--- 首先,我们在开始前提出一个问题: 1.在运行时,对于一个java类,能否知道属性和方法:能否去调用它的任意方法? 答案是肯定的. 本节所有目录如下: 什么是JAVA的反射机制 JDK中提供的Reflection API JAVA反射机制提供了什么功能 获取类的Class对象 获取类的Fields 获取类的Method 获取类的Constructor 新建类的实例        Class<T>的函数newInstance        通过Constructor对象的

java反射机制详解和应用

1反射机制是什么 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 2反射机制能做什么 反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类: 在运行时构造任意一个类的对象: 在运行时判断任意一个类所具有的成员变量和方法: 在运行时调用任意一个对象的方法: 生成动态代理. 3反射机制的相关API 通过一个对象获得完整的包名和类名 pub

[转]Java反射机制详解

目录 1反射机制是什么 2反射机制能做什么 3反射机制的相关API ·通过一个对象获得完整的包名和类名 ·实例化Class类对象 ·获取一个对象的父类与实现的接口 ·获取某个类中的全部构造函数 - 详见下例 ·通过反射机制实例化一个类的对象 ·获取某个类的全部属性 ·获取某个类的全部方法 ·通过反射机制调用某个类的方法 ·通过反射机制操作某个类的属性 ·反射机制的动态代理 4反射机制的应用实例 ·在泛型为Integer的ArrayList中存放一个String类型的对象. ·通过反射取得并修改数