反射(1)

来源:互联网 发布:键盘记录软件 编辑:程序博客网 时间:2024/05/16 12:31

什么是反射?

基于java万物皆对象的原则,一个类的字节码文件通过类加载器读取到内存,封装成一个Class对象(Cass对象内部包含nConstructor对象,nMethod对象,nField对象),通过这个Class对象,可以获取类的信息,可以构造类的对象,可以调用类的方法,可以获取类的属性,给属性赋值等,这就是反射。

 

Student s = new Student();

底层走反射:

Class clz = Class.forName("xxxx");

Student s = (Student)clz.newInstance();

 

 Class对象(重点)

    Class对象结构:

        1Class对象:代表整个类的信息,类的名称,类的父类和接口

            nConstructor对象:代表类的构造方法,创建类的对象

            nMethod对象:代表类的普通方法,调用类的方法

            nFiled对象: 代表类的属性(字段),给类的属性赋值,获取属性值

 

 

反射的核心方法:

    Class对象:

        getName() 类名

        getSimpleName() 类简单名

        getSuperClass()  父类

        getInterfaces() 接口

        getConstructor() 构造方法(公开的)

        getDeclareConstructor() 构造方法(公开和私有的)

        getMethod()  普通方法(公开的)

        getDeclareMethod()    普通方法(公开和私有的)

        getField()  属性(公开的)

        getDeclareFiled()  属性(公开和私有的)

        getGenericSuperClass()  获取泛型的父类

 

 

public void test()throws Exception{

//1.得到Class类的对象

方式一:

Class clazz = Student.class;

方式二: (依赖性比较低,只依赖字符串)

Class clazz = Class.forName("com.djz.Student");

方式三:

Class clazz = new Student().getClass();

//2.得到类名

System.out.println(clazz.getName());//全名(包含包结构)

System.out.println(clazz.getSimpleName());//简单名

//3.得到类的继承结构

//得到Student类的父类

Class parent = clazz.getSuperclass();

System.out.println(parent.getSimpleName());

//4.得到类的接口

Class[] interArray = clazz.getInterfaces();

for (Class cla : interArray) {

System.out.println(cla.getSimpleName());

}

}

 

 

   Constuctor对象:

     newInstace(参数)  构造类的对象

public void test() throws Exception{

//1)通过Class类对象得到Method类对象

Class clazz = Class.forName("com.djz.Student");

Object obj = clazz.getConstructor(null).newInstance(null);

/**

 *  getMethod() :获取类上的公共的方法(public

 *  getDeclaredMethod(): 获取类上的所有方法(公共和私有的方法)

 */

/**

 * 参数一: 方法名

 * 参数二: 形式参数列表

 */

Method setName = clazz.getMethod("setName", String.class);

//2)通过Method对象调用方法

/**

 * 参数一调用方法所需的对象

 * 参数二:实际参数值

 */

setName.invoke(obj, "jacky"); // obj.setName("jacky")

System.out.println(obj);

Method getName = clazz.getMethod("getName"null);

//调用方法,接收方法返回值

Object result = getName.invoke(obj, null)// obj.getName();

System.out.println(result);

}

 

    Method对象:

      invoke(对象,参数调用类的方法

 

public void test() throws Exception{

//1)通过Class类对象得到Method类对象

Class clazz = Class.forName("com.djz.Student");

Object obj = clazz.getConstructor(null).newInstance(null);

/**

 *  getMethod() :获取类上的公共的方法(public

 *  getDeclaredMethod(): 获取类上的所有方法(公共和私有的方法)

 */

/**

 * 参数一: 方法名

 * 参数二: 形式参数列表

 */

Method setName = clazz.getMethod("setName", String.class);

//2)通过Method对象调用方法

/**

 * 参数一调用方法所需的对象

 * 参数二:实际参数值

 */

setName.invoke(obj, "jacky"); // obj.setName("jacky")

System.out.println(obj);

Method getName = clazz.getMethod("getName"null);

//调用方法,接收方法返回值

Object result = getName.invoke(obj, null)// obj.getName();

System.out.println(result);

}

 

 Filed对象:

        set(对象,参数) 给类的属性赋值

        get(对象) 获取类的属性值

 

public void test() throws Exception{

//1)通过Class得到Field类对象

Class clazz = Class.forName("com.djz.Student");

//Object obj = clazz.getConstructor(null).newInstance(null);

Object obj = clazz.newInstance();//这是简化版本,但只能使用无参的构造方法构造

 

/**

 *  getDeclaredField:得到任意修饰的属性(public/private

 *  getField(): 得到公开的属性(public

 */

Field name = clazz.getDeclaredField("name");

//2)得到属性名

System.out.println(name.getName());//name

//得到属性的类型

System.out.println(name.getType()); //String

/**

 * 给属性赋值:

 *      以前: s.name="eric"

 *    现在:使用反射技术直接类似地直接给属性赋值,而不是调用setName方法赋值

 */

 

/**

 * 参数一: 赋值给哪个对象

 * 参数二: 赋值

 */

//打破私有修饰符的限制

name.setAccessible(true);//忽略private修饰符

name.set(obj, "rose");

 

/**

 * 获取属性值

 */

Object result = name.get(obj);

System.out.println(result);

}

0 0
原创粉丝点击