反射

基础概念


什么是反射

运行时动态获取类的内部信息的一种方式。

反射的作用

1. 可以通过反射机制发现对象的类型,发现类型的方法/属性/构造器

2. 可以创建对象并访问任意对象方法和属性等

Class类加载

类加载到内存:Java将磁盘类文件加载到内存中为一个对象(实例),这个对象是Class类的实例

Class实例代表Java中的类型

1. 获得基本类型实例

    int.class

    long.class ....

2. 获得类类型(Class)实例

    Class cls = String.class;

    Class cls = Class.forName(“java.lang.String”);

    Class cls = “abc”.getClass();

    以上方法获得cls是同一个对象,就是Sting类内存加载的结果

典型应用

IDE的提示、JavaBean的拷贝、简单工厂

 

通过反射创建对象实例


 案例

public static Object create(String classname) {
        try{
            // 1、加载类
            Class cls = Class.forName(classname);
            // 2、创建类实例
            Object obj = cls.newInstance();
            return obj;
        }
        catch(Exception e){
            throw new RuntimeException("创建对象失败", e);
        }
}

class.forName作用

要求JVM查找并加载指定的类(加载dao方法区中),也就是说JVM会执行该类的静态代码段。

当直接new对象实例化后该类的静态代码块也会被执行,但是这样不利于动态读取配置文件创建连接,因此一般都使用Class.forName的形式。

JDBC加载驱动类

常见的是JDBC连接数据库的时候加载驱动类。注册一个数据库驱动。class.forname(“oracle.jdbc.driver.OracleDriver”);该代码是加载oracle驱动类,完成驱动的注册。执行驱动类的一些静态代码块。

静态代码块的主要内容是:

DriverManager.registerDriver(new OracleDriver());向DriverManager注册自己。(所谓注册就是创建Driver实例,添加到驱动列表中)。

注册成功后,就可以与数据库进行连接。

DriverManager.getConnection(url, user, password);

这个方法主要实现的是找到注册时创建的oracleDriver对象,调用OracleDriver的connect(url)来实现数据库的连接。对数据库操作时,OracleDriver调用Oracle对Connection,Statement,ResultSet几个接口的实现类来完成功能。

OracleDriver这个类是用来管理Connection,Statement,ResultSet这几个接口的

DriverManger是用来管理OracleDrier类的。

 

Class类的相关方法


Calss(类类型):用于存储类的信息,诸如类名、有哪些属性,方法,构造器,父类型

Class类的实例表示正在运行的Java类或者接口。任何Java的类或者接口都是Class类的一个实例。

Class clazz=String.class;

clazz.getName()  类名:java.lang.String

clazz.getSimpleName()  简单类名:String

clazz.getSuperclass().getName()  父类型名称:java.lang.Object

Class[] classes=clazz.getInterfaces();  获取所实现的接口信息,返回值是数组类型

Method[] methods=clazz.getMethods();  获取该类拥有的public方法信息

clazz.getDeclaredMethod(方法名,参数类型);  获取某个具体的方法

Field[] fields=clazz.getFields();  获取public属性信息

Field[] fields=clazz.getDeclaredFields();  获取所有属性

Field field=clazz.getDeclaredField("name");  获取一个具体的属性

 

public class BaseClass {
    int id;
    private String name;
    public double grade;

    public BaseClass() {
    }

    public BaseClass(int id, String name, double grade) {
        super();
        this.id = id;
        this.name = name;
        this.grade = grade;
    }

    public void fun1() {
        System.out.println("无返回值,无参数的方法");
    }

    public String fun2(int a) {
        return this.name + "," + a;
    }
}

 

Filed类的相关方法


 

field.getModifiers()  返回该属性的修饰符信息(private static final...),返回是整数

Modifier.toString(field.getModifiers())  把整数转换成相应的private public..

field.getType().getSimpleName()  属性类型

field.getName()  属性名

Field field=clazz.getDeclaredField(属性名");  获得某一个具体的属性值

field.setAccessible(true);  允许访问私有属性

Object value=field.get(具体的对象引用obj);  获取具体对象obj中该属性值

field.set(obj, "李四");  对具体对象object的属性设置值”张三”,该属性就是field对应的属性

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

        Class clazz = Class.forName("com.org.qin.test.BaseClass");
        Field[] fields = clazz.getDeclaredFields();
        // 访问BaseClass的属性信息,修饰符 类型 属性名
        for(Field field : fields){
            System.out.print(Modifier.toString(field.getModifiers()) + "  " + field.getType().getSimpleName() + "  "
                    + field.getName());
            System.out.println();
        }
        BaseClass obj = new BaseClass(1, "张三", 2);

        // 获取某一个具体的属性
        Field field = clazz.getDeclaredField("name");
        // 允许访问私有属性
        field.setAccessible(true);
        // 获取属性中的值
        Object value = field.get(obj);
        System.out.println(value);

        // 为对象的属性赋值
        field.set(obj, "李四");
        System.out.println(field.get(obj));
}

 

Method类的相关方法


 

method.getReturnType()  方法返回值类型

method.getName()   方法名

Class[] pTypes=method.getParameterTypes();   方法参数类型

method.invoke(obj, new Class[]{});  调用某个具体的方法

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

        Class clazz = BaseClass.class;
        Method[] methods = clazz.getDeclaredMethods();

        // 获取类中所有方法信息 返回值类型 方法名 参数类型
        for(Method method : methods){
            System.out.print(method.getReturnType().getSimpleName() + "  " + method.getName());
            Class[] pTypes = method.getParameterTypes();
            System.out.print("(");
            for(Class t : pTypes){
                System.out.print(t.getSimpleName());
            }
            System.out.println(")");
        }

        // 获取类中的某个指定方法
        Method method = clazz.getDeclaredMethod("fun1", new Class[]{});// 没有参数,放入一个空数组就行

        // 调用方法
        BaseClass obj = new BaseClass(1, "张三", 2);

        // method.invoke(obj,null);//无参数可以写null或者new Object[]{}
        method.invoke(obj, new Object[]{});

        // 获取有参数方法,并且调用
        Method method2 = clazz.getDeclaredMethod("fun2", new Class[]{int.class});
        System.out.println(method2.invoke(obj, new Object[]{3}));
}

 

constructor类的相关方法


 

constructor.getParameterTypes();  获得构造器参数类型

constructor.getModifiers();  获得构造器修饰符信息

constructor.getName();  构造器名称

clazz.getConstructor(new Class[]{...});  获得指定构造器(根据类型)

BaseClass obj=(BaseClass) constructor.newInstance(new Object[]{....});//使用构造器创建对象

案例

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

         Class clazz=BaseClass.class;

         Constructor[] constructors=clazz.getConstructors();

         for(Constructor constructor:constructors){

                  Class[] types=constructor.getParameterTypes();

                  System.out.print(Modifier.toString(constructor.getModifiers()) +"  "+constructor.getName());

                  System.out.print("(");

                  for(Class t:types){

                           System.out.print(t.getSimpleName()+" ");

                  }

                  System.out.println(")");

         }

         /获得指定的构造器

         Constructor constructor=clazz.getConstructor(

new Class[]{int.class,String.class,double.class,double.class});

         //用构造器创建对象

         BaseClass obj=(BaseClass) constructor.newInstance(new Object[]{1,"张三",20,2});

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

}

 

7、JavaBean拷贝

1)什么是JavaBean

   一种Java类,重用的组件,符合一定设计规范的

2)符合规范如下

        a、公共且完整的类

        b、所有属性需要隐藏

        c、提供公共的可访问私有属性的途径(getXXX,setXXX)

        d、布尔类型的属性命名时把get/set换成is

        e、一定要提供一个无参的构造器

 

posted on 2017-04-05 17:15  芹derella  阅读(111)  评论(0编辑  收藏  举报