java反射知识总结

一、实现反射的三种方式
1.类 .getClass()
首先在object超类中有个public final Class<?> getClass(),final意味着此方法不能被重写,所有类的实例化对象都可以调用。缺点:这种方式使用率较低,因为必须首先实例化对象才能调用这个方法。
2.包.类.class
不需要指定操作类的实例化对象,直接通过类名称就可以完成,比如java .util.Date.class hibernate 及mybatic。缺点:这种方式必须明确结构,即类必须存在,不是特别灵活。
3.Class.forName(类名称)
在Class类中有public static Class<?> forName(String className) throws ClassNotFoundException方法。在工厂类设计模式有用到及jdbc加载驱动的时候。这种方式相对比较灵活,没有很强的严谨性,操作的类可以不存在,不会出现语法错误,但是运行时,必须设置指定的类。

二、反射实例化的方式
在获取Class类对象之后,才能操作实例化对象的方法。public T newInstance() throws InstantiationException, IllegalAccessException
异常信息解释:InstantiationException:无法实例化。原因:没有无参构造方法或者类名称错误
IllegalAccessException:错误的访问,构造方法私有化
因此,newstance() 只能调用类中的无参构造方法,相当于new一个实例化对象。两者区别不大,反射灵活性更高。若想实例化有参构造,可以调用构造函数,下面内容会解决这个问题。

三、反射的核心成员
java.lang.reflect包中有三大核心类:java.lang.reflect.Constructor<T>,java.lang.reflect.Method,java.lang.reflect.Field
1.构造函数 java.lang.reflect.Constructor<T>
获取全部构造方法:public Constructor<?>[] getConstructors() throws SecurityException
获取指定构造方法:public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException,SecurityException
获取构造方法名称:public String getName()
获取修饰符:public int getModifiers(),注意这返回的是int类型的数字,所有修饰符都是通过数字编号取得的,比如1对应public,用 toString()方法可以进行还原操作。
获取参数类型:public Class<?>[] getParameterTypes()
获取构造方法上的全部异常信息:public Class<?>[] getParameterTypes()

下面是有参构造的实例化方法,不推荐使用有参的实例,相对复杂,必须提供全参。一般构造简单的无参的java类实例化

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

}

public class Demo {

    public static void main(String args[]) throws Exception {
        Class<?> demoClass = Class.forName("com.qiuyiliang.Person");
        Constructor<?> personCst = demoClass.getConstructor(String.class,Integer.class);
        Person person = (Person)personCst.newInstance("秋意凉",100);
        System.out.println(person);
    }
}

2.java.lang.reflect.Method
获取所有方法:public Method[] getDeclaredMethods()throws SecurityException//此方法不包括继承的方法,只是本类中所有的方法
获取所有方法:public Method[] getMethods() throws SecurityException//获取所有方法 包括继承来的
获取返回值类型:public Class<?> getReturnType()
调用本类的方法:public Object invoke(Object obj,Object... args) throws IllegalAccessException,IllegalArgumentException,InvocationTargetException
注意:必须保证已经存在本类的实例化对象,而很方便的是这种实例化对象可以使用Object来代替,可以直接利用Class类反射实例化对象,而后通过Objcect对象操作,没有必要向下转型操作。原则上简单的java类中的属性一定要经过封装,编写setter getter方法。通过setter的方法设置属性的值。
操作method的代码(有参构造,有返回值,有参数):

class Person{
    private String name;
    private Integer age;
    public Person(String name,Integer age){
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    public String running(String str) {
        System.out.println(str);
        return str;
    }

public class Demo {
  public static void main(String args[]) throws Exception {
        Class<?> demoClass = Class.forName("com.qiuyiliang.Person");
        Constructor<?> constc = demoClass.getConstructor(String.class,Integer.class);
        Object object = constc.newInstance("秋意凉",100);
        Method method = demoClass.getMethod("running", String.class);
        Object val = method.invoke(object, "running...");
        System.out.println(val);
    }
}

3 . java.lang.reflect.Field(属性成员)
获取成员:public Field[] getFields() throws SecurityException //获取全部包括继承的。但无法获取私有的属性
获取成员:public Field[] getDeclaredFields() throws SecurityException //获取全部本类的申明的属性,不包括继承的
获取某一个属性:public Field getField(String name) throws NoSuchFieldException, SecurityException
获取某一个属性:public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException 同理

获取属性的类型:public Class

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


    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String running(String str) {
        System.out.println(str);
        return str;
    }

}

public class Demo {

    public static void main(String args[]) throws Exception {
        Class<?> demoClass = Class.forName("com.qiuyiliang.Person");
        Constructor<?> constc = demoClass.getConstructor(String.class,Integer.class);
        Field declaredField = demoClass.getDeclaredField("name");
        Object object = constc.newInstance("秋意凉",100);
        Method setMethod = demoClass.getMethod("setName", declaredField.getType());   //此处可灵活处理  “set”+declaredField.getName()
        Method getMethod = demoClass.getMethod("getName");                            //此处可灵活处理  “get”+declaredField.getName()
        setMethod.invoke(object, "秋意凉2");
        Object getObj = getMethod.invoke(object);
        System.out.println(getObj);
    }
}

四、反射的应用 :(待续…)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值