发表于: 2018-03-11 20:59:56

1 752


今天完成的事情:

学习Java基础知识——反射 

获取类对象

    1 类对象:所有的类,都存在一个类对象,这个类对象用于提供类本身的信息,比如有几种构造方法,有多少属性,有哪些普通方法

   2 获取类对象的三种方式:

      Class.forName;Hero.class;new Hero().getClass()

      一个JVM中,一种类,只会有一个类对象存在。这是因为一个ClassLoader下,一种类,只会有一个类对象存在。通常一个JVM下,只会有一个ClassLoader

    3 获取类对象的时候,会导致类属性被初始化。无论什么途径获取类对象,都会导致静态属性被初始化,而且只会执行一次。(除了直接使用 Class c = Hero.class 这种方式,这种方式不会导致静态属性被初始化)


使用反射机制创建一个对象

package reflection;

import java.lang.reflect.Constructor;

import charactor.Hero;

public class TestReflection {

    public static void main(String[] args) {

    //传统的使用new的方式创建对象

        Hero h1 =new Hero();

        h1.name = "teemo";

        System.out.println(h1);  

        try {

        //使用反射的方式创建对象

            String className = "charactor.Hero";

            //类对象

            Class pClass=Class.forName(className);

            //构造器

            Constructor c= pClass.getConstructor();

            //通过构造器实例化

            Hero h2= (Hero) c.newInstance();

            h2.name="gareen";

            System.out.println(h2);

        } catch (Exception e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

}


通过反射机制修改对象的属性

1。一般只能修改public修饰的成员,对于private修饰的成员,需要使用setAccessible(true)才能访问和修改

2。例如:

package reflection;

import java.lang.reflect.Field;

import charactor.Hero;

public class TestReflection {

    public static void main(String[] args) {

            Hero h =new Hero();

            //使用传统方式修改name的值为garen

            h.name = "garen";

            try {

            //获取类Hero的名字叫做name的字段

                Field f1= h.getClass().getDeclaredField("name");

                //修改这个字段的值

                f1.set(h, "teemo");

                //打印被修改后的值

                System.out.println(h.name);       

            } catch (Exception e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

    }

}

3。getField和getDeclaredField的区别

getField 只能获取public的,包括从父类继承来的字段。

getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段。 ( 这里只能获取到private字段,但并不能访问该private字段的,除非加上setAccessible(true))


通过反射机制,调用一个对象的方法

首先为Heroname属性,增加settergetter

package charactor;


public class Hero {

public String name;

public float hp;

public int damage;

public int id;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Hero(){

}

public Hero(String string) {

name =string;

}

@Override

public String toString() {

return "Hero [name=" + name + "]";

}

public boolean isDead() {

// TODO Auto-generated method stub

return false;

}

public void attackHero(Hero h2) {

// TODO Auto-generated method stub

}


}

通过反射机制调用Hero的setName



package reflection;


import java.lang.reflect.Method;


import charactor.Hero;


public class TestReflection {


public static void main(String[] args) {

Hero h = new Hero();


try {

// 获取这个名字叫做setName,参数类型是String的方法

Method m = h.getClass().getMethod("setName", String.class);

// 对h对象,调用这个方法

m.invoke(h, "盖伦");

// 使用传统的方式,调用getName方法

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


} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}


}

}


反射方式

使用反射方式,首先准备一个配置文件,就叫做spring.txt, 放在src目录下。 里面存放的是类的名称,和要调用的方法名。

在测试类Test中,首先取出类名称和方法名,然后通过反射去调用这个方法。

当需要从调用第一个业务方法,切换到调用第二个业务方法的时候,不需要修改一行代码,也不需要重新编译,只需要修改配置文件spring.txt,再运行即可。

这也是Spring框架的最基本的原理,只是它做的更丰富,安全,健壮


创建spring项目

IDEA自带spring,可以直接spring

上图中的ctreate empty spring-config.xml记得勾选不然没有配置文件

然后命名

进来后项目结构如下


明天计划的事情:

开始写连接数据库的代码

 
遇到的问题:

 
收获:

初识IOC,DI。这两个概念就是帮你把项目打包,jiejue配置的问题


返回列表 返回列表
评论

    分享到