Java反射与类操作

  1. java是一个纯面向对象语言,反射也是一个自醒,获取类的信息
  2. 反射指的是对象的反向处理操作,在正常情况下我们是通过包名.类名找到类,而“反”则是通过Object的方法public final native Class<?> getClass();返回一个Class类对象,在反射中看中的不是一个对象,而是对象身后的组成(类、构造、方法、成员)
//反向操作
Date date1 =new Date();
Class cla= date1.getClass();
System.out.println(cla);
//calss.java.util.Date
  1. 取得父类的属性
    在Class类中提供有两组取得属性的方法:
  • 第一组(父类中)-取得类中全部属性: public Field[] getFields() throws SecurityException
  • 第一组(父类中)-取得类中指定名称属性: public Field getField(String name) throws
    NoSuchFieldException, SecurityException
  • 第二组(本类中)-取得类中全部属性: public Field[] getDeclaredFields() throws SecurityException
  • 第二组( 本类中)-取得类中指定名称属性 : public Method getDeclaredMethod(String name, Class<?>… parameterTypes) throws NoSuchMethodException, SecurityException
public class Attribute {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException, NoSuchMethodException {
        Class<?> m = Class.forName("com.bittech.Student");
        //取得父类中全部属性
        Field[] files = m.getFields();
        for (Field filed : files) {
            System.out.println(filed);
        }
        System.out.println("---");
        //取得父类中的指定属性
        Field files2 = m.getField("school");
        System.out.println(files2);
        System.out.println("---");
        //取得本类中的全部属性
        Field[] files3 = m.getDeclaredFields();
        for (Field f : files3) {
            System.out.println(f);
        }
        System.out.println("---");
        Object obj = m.newInstance();
        Field fi = m.getDeclaredField("school");//null
        fi.set(obj,"ii");//相当于school="ii"
        //取得属性
        System.out.println(fi.get(obj));
    }
}

class Teacher {
    public int age;
    public String name;
}
class Student extends Teacher {
    public String school;
}
  1. 反射取得包名称、父类名称、全部构造方法等
    Class类通过反射实例化类对象的时候,只能够调用类中的无参构造。如果现在类中没有无参构造则无法使用Class类调用,只能够通过明确的构造调用实例化处理。
interface IFruit1{}
interface IMessage{}
class CLS implements IFruit1,IMessage{}
class Person{
    public Person(){}
    public Person(String name){}
    public  Person(String name,int age){}

}
public class SuperClass {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class<?> cls=CLS.class;
        //取得包名称
        System.out.println(cls.getPackage().getName());
        //取得父类的名称
        System.out.println(cls.getSuperclass().getName());
        //取得实现的父接口对象
        Class<?>[] iClass=cls.getInterfaces();
        for(Class<?> class1:iClass){
            System.out.println(class1.getName());
        }
        System.out.println("---");
        //取得类中的全部构造
        Class<?> cls1=Person.class;
        Constructor<?>[] constructors=cls1.getConstructors();
        for(Constructor<?> constructor :constructors){
            //只返回包名和类名
            System.out.println(constructor.getName());
            //返回构造方法的全部信息
            System.out.println(constructor);
        }
        System.out.println("----");
        //取得指定参数类型的构造方法对象
        Constructor<?> cons=cls1.getConstructor(String.class,int.class);
        System.out.println(cons.newInstance("yu",23));
    }
}

  1. 反射调用普通方法
  • 取得全部普通方法: public Method[] getMethods() throws SecurityException
  • 取得指定普通方法: public Method getMethod(String name, Class<?>… parameterTypes)
  • 以上两个方法泛型的类型是java.lang.reflect.Method类的对象,在此类中提供有一个调用方法的支持:public Object invoke(Object obj, Object… args)throws IllegalAccessException, IllegalArgumentException,InvocationTargetException
 
public class Reflection {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, ClassNotFoundException, InvocationTargetException {
        //  Class<?> cls3 = Person1.class;

        //1.所有的普通方法必须在有实例化对象之后才可以进行调用
        //取得一个类中全部普通方法
//        Method[] method = cls3.getMethods();
//        for (Method m : method) {
//            System.out.println(m);
//        }
        Class<?> cls4 = Class.forName("com.bittech.Person1");
        Object obj = cls4.newInstance();
        // 取得setName这个方法的实例化对象,设置方法名称与参数类型
        Method setMethod = cls4.getMethod("setName", String.class);
        // 随后需要通过Method类对象调用指定的方法,调用方法需要有实例化对象
        // 同时传入参数
        setMethod.invoke(obj, "yu"); // 相当于Person对象.setName("yuisama") ;
        Method getMethod = cls4.getMethod("getName");
        Object result1 = getMethod.invoke(obj); // 相当于Person对象.getName() ;
        System.out.println(result1);

    }
}

class Person1 {
    private String name;
    private int age;

    public Person1() {
    }

    public Person1(String name, int 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 int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
  1. 反射封装
    在AccessibleObject类中提供有一个方法:动态设置封装:public void setAccessible(boolean flag) throws SecurityException
 * 1. 设置属性内容 : public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException
 * 2. 取得属性内容 : public Object get(Object obj) throws IllegalArgumentException, IllegalAccessException
 * 3.取得属性类型 :public Class<?> getType()
 */
public class Encapsulate {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {

        Class<?> cls5 = Class.forName("com.bittech.Friend1");
        //实例化本类对象
        Object obj = cls5.newInstance();
        //操作name属性
        Field field0 = cls5.getDeclaredField("name");

        //设置属性内容,等价于对象.name="ii",设置封装,运行的时候会出错
        //field0.set(obj, "ii");
        //取消封装
        field0.setAccessible(true);
        field0.set(obj, "i");

        //取得属性内容
        System.out.println(field0.get(obj));
        //包.类
        System.out.println(field0.getType().getName());
        //类名称
        System.out.println(field0.getType().getSimpleName());
    }
}

class Friend1 {
    private String name;
}
i
java.lang.String
String

获取包、继承得类,只返回一个类单继承

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值