获取运行时类的其它结构、调用指定的属性和方法

环境准备:
包结构:

这里写图片描述

===========================
Person.java

package com.atguigu.java;

import java.io.Serializable;

public class Person extends Creature<String> implements Comparable,Serializable{
    String name;
    private int age;
    public String id;

    public Person() {
        super();
        System.out.println("Person()....");
    }

    private Person(String name){
        this.name = name;
    }

    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }

    @MyAnnotation("atguigu")
    public static void show() throws RuntimeException{
        System.out.println("我是一个人!");
    }

    @Override
    public int compareTo(Object o) {
        // TODO Auto-generated method stub
        return 0;
    }

    private void info(){
        System.out.println("君生我未生 我生君已老");
    }

    public String getNation(String nation,int year){
        System.out.println("nation : " + nation);
        return nation + "!!";
    }
}

=============================
Creature.java

package com.atguigu.java;

public class Creature<T> {//生物
    public double weight;//体重

    public void breath(){
        System.out.println("呼吸");
    }
}

==============================

获取运行时类的其它结构:

package com.atguigu.java;

import java.lang.reflect.Constructor;
import java.lang.reflect.Type;

import org.junit.Test;

public class OtherTest {
    //获取运行类所在的包
    @Test
    public void getPackageTest(){
        Class clazz = Person.class;

        Package pack = clazz.getPackage();
        System.out.println(pack);
    }

    //获取运行时类实现的接口
    @Test
    public void getInerfacesTest(){
        Class clazz = Person.class;

        Class[] interfaces = clazz.getInterfaces();
        for(int i = 0;i <interfaces.length;i++){
            System.out.println(interfaces[i]);
        }
    }

    //获取运行时类带泛型的父类
    @Test
    public void getSuperClassTest1(){
        Class clazz = Person.class;
        Type superclass = clazz.getGenericSuperclass();
        System.out.println(superclass);
    }

    //获取运行时类的父类
    @Test
    public void getSuperClassTest(){
        Class clazz = Person.class;
        Class superclass = clazz.getSuperclass();
        System.out.println(superclass);
    }

    @Test
    public void getConstructorTest(){
        Class clazz = Person.class;
        //getDeclaredConstructors():获取对应的运行时类中声明的所有的构造器
        Constructor[] cons = clazz.getDeclaredConstructors();
        for(int i = 0;i < cons.length;i++){
            System.out.println(cons[i]);
        }
    }
}

=================================
调用指定的属性和方法:

package com.atguigu.java;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.junit.Test;

/*
 * 反射的应用三:如何调用运行时类中指定的结构:属性、方法、构造器(掌握)
 */
public class ReflectionTest2 {
    @Test
    public void staticMethodTest() throws Exception{
        Class clazz = Person.class;

        //public static void show() throws RuntimeException{}
        Method m = clazz.getDeclaredMethod("show");
        m.setAccessible(true);
        Object returnValue = m.invoke(Person.class);
        System.out.println(returnValue);
    }

    // 调用指定的方法
    @Test
    public void MethodTest() throws Exception {
        Class clazz = Person.class;
        //1.getDeclaredMethod(String methodName,Class ... paramTypes):
        Method method = clazz.getDeclaredMethod("getNation",String.class,int.class);

        //辅助的:
        Person p = (Person) clazz.newInstance();

        //2.调用setAccessible(true),保证此方法是可访问的
        method.setAccessible(true);
        //3.调用此方法:object invoke(Object obj,Object ... paramValues):
        //invoke()的返回值即为调用此方法对应的运行时类中的方法的返回值。
        Object returnVal = method.invoke(p, "CHN",10);
        System.out.println(returnVal);

    }

    // 调用指定的属性
    @Test
    public void FieldTest() throws Exception {
        Class clazz = Person.class;

        // 1.获取对应的运行时类中指定的属性
        // getField(String fieldName):只能获取对应的运行时类中声明为public的属性
        // 不建议使用此方法
        Field field1 = clazz.getField("id");
        // Field field1 = clazz.getField("name");

        // System.out.println(field1);

        // 建议使用:1.getDeclaredField(String fieldName):获取运行时类指定属性名的方法。
        // 任何权限修饰符修饰的都可以获取
        Field field2 = clazz.getDeclaredField("age");
        // System.out.println(field2);

        // 辅助操作:创建运行时类的对象
        Person p = (Person) clazz.newInstance();
        // 2.调用setAccessible(true),保证此属性是可访问的
        field2.setAccessible(true);
        // 3.get(Object obj):获取指定运行时类的对象obj的当前属性的值
        System.out.println(field2.get(p));
        // set(Object obj,Object fieldValue):设置运行时类的对象obj的当前属性值为fieldValue
        field2.set(p, 23);
        System.out.println(field2.get(p));
    }
}

=========================
未完待续!

posted @ 2017-09-05 23:42  libingshen  阅读(97)  评论(0编辑  收藏  举报