• Java反射复习


    三种实例化对象:

    1、Class<?> cls = Class.forName("java.util.Date") ; ***
    System.out.println(cls.getName());
    
    2、类.class
    
    3、对象.getClass
    Class<?> cls = Class.forName("java.util.Date") ;
    Object obj = cls.newInstance() ; // 实例化对象,等价于 new java.util.Date()  等价于  Date date  = new Date()
    class Main{
        public static void main(String[] args) {
            System.out.println(new java.util.Date()==new java.util.Date());
            //false
        }
    }
    获得包名:
    Class<?> cls = CLS.class ; // 取得Class类对象
    System.out.println(cls.getPackage().getName());
    
    获得父类接口:
    Class<?> cls = CLS.class ; // 取得Class类对象
    System.out.println(cls.getSuperclass().getName());
    // 取得实现的父接口对象
    Class<?>[] iClass = cls.getInterfaces() ;
    for (Class<?> class1 : iClass) {
    System.out.println(class1.getName());
    }
    
    
    
    获得构造方法:
    Class<?> cls = Person.class ;
    // 取得类中的全部构造
    Constructor<?>[] constructors = cls.getConstructors() ;
    for (Constructor<?> constructor : constructors) {
    System.out.println(constructor);
    }
    
    
    
    获取指定参数的构造:
    public Constructor<T> getConstructor(Class<?>... parameterTypes)
    throws NoSuchMethodException, SecurityException
    
    在定义简单java类的时候一定要保留有一个无参构造
    
    Class类通过反射实例化类对象的时候,只能够调用类中的无参构造。如果现在类中没有无参构造则无法使用Class
    类调用,只能够通过明确的构造调用实例化处理。

    反射获得Date构造方法:

    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    import java.text.SimpleDateFormat;
    
    class Main{
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException,
                IllegalAccessException, InvocationTargetException, InstantiationException {
          Class<?> cls =   Class.forName("java.text.SimpleDateFormat");
            Constructor<?>[] constructor = cls.getConstructors();
            for (Constructor<?> constructor1 : constructor){
                System.out.println(constructor1);
            }
    
    //        SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    //      String str = simpleDateFormat.format(new Date());
    //        System.out.println(str);
    
            Constructor<?> cons = cls.getConstructor(String.class);
           System.out.println((SimpleDateFormat)cons.newInstance("yyyy-MM-dd HH:mm:ss"));
        }
    }

    反射获得指定参数构造方法

    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    class Person {
        private String name ;
        private int age ;
        public Person(String name,int age) {
            this.name = name ;
            this.age = age ;
        }
        @Override
        public String toString() {
            return "Person [name=" + name + ", age=" + age + "]";
        }
    }
    class Test {
        public static void main(String[] args) throws InstantiationException,
                IllegalAccessException, NoSuchMethodException, SecurityException,
                IllegalArgumentException, InvocationTargetException {
            Class<?> cls = Person.class;
    // 取得指定参数类型的构造方法对象
            Constructor<?> cons = cls.getConstructor(String.class, int.class);
            System.out.println(cons.newInstance("yuisama", 29));
        }
    }
    public Method[] getMethods() throws SecurityException
    
    
    public Method getMethod(String name, Class<?>... parameterTypes)
    
    
    public static void main(String[] args) throws Exception {
    Class<?> cls = Person.class ;
    Method[] methods = cls.getMethods() ;
    for (Method method : methods) {
    System.out.println(method);
    }
    }
    import java.lang.reflect.Method;
    class Person {
    private String name ;
    private int age ;
    public Person() {}
    public Person(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;
    }
    }
    
    public class Test {
    public static void main(String[] args) throws Exception {
    Class<?> cls = Class.forName("www.java.hhy.Person") ;
    // 任何时候调用类中的普通方法都必须有实例化对象
    Object obj = cls.newInstance() ;
    // 取得setName这个方法的实例化对象,设置方法名称与参数类型
    Method setMethod = cls.getMethod("setName", String.class) ;
    // 随后需要通过Method类对象调用指定的方法,调用方法需要有实例化对象
    // 同时传入参数
    setMethod.invoke(obj, "yuisama") ; // 相当于Person对象.setName("yuisama") ;
    Method getMethod = cls.getMethod("getName") ;
    Object result = getMethod.invoke(obj) ; // 相当于Person对象.getName() ;
    System.out.println(result) ;
      }
    }

    此类操作的好处是:不再局限于某一具体类型的对象,而是可以通过Object类型进行所有类的方法调用

    ---------------------------------------------------------    属性的获取
    public class Test {
    public static void main(String[] args) throws Exception {
    Class<?> cls = Class.forName("www.bit.java.testthread.Student") ;
    { // 普通代码
    // 第一组-取得父类中全部属性
    Field[] fields = cls.getFields() ;
    for (Field field : fields) {
    System.out.println(field) ;
    }
    }
    System.out.println("------------------------");
    {
    // 第二组-取得类中全部属性
    Field[] fields = cls.getDeclaredFields() ;
    for (Field field : fields) {
    System.out.println(field);
    }
    }
    }
    }
    package www.bit.java.testthread;
    import java.lang.reflect.Field;
    class Person {
    private String name ;
    }
    public class Test {
    public static void main(String[] args) throws Exception {
    Class<?> cls = Class.forName("www.bit.java.testthread.Person") ;
    // 实例化本类对象
    Object obj = cls.newInstance() ;
    // 操作name属性
    Field nameField = cls.getDeclaredField("name") ;
    nameField.set(obj, "yuisama") ; // 相当于对象.name = "yuisama"
    System.out.println(nameField.get(obj)); // 取得属性
    }
    }

    自定义类加载器
    cls.getClassLoader() = AppClassLoader(应用程序类加载器)
    cls.getClassLoader().getParent()) = ExtClassLoader(扩展类加载器);
    最顶层: Bootstrap(启动类加载器): 启动类加载器无法被Java程序直接引用。
    -------------------------------------------------------------------
    双亲委派模型:

    我们的应用程序都是由这三种加载器互相配合进行加载的,如果有必要,还可以加入自定义的类加载器。
    双亲委派模型要求除了顶层的父类加
    载器外,其余的类加载器都应有自己的父类加载器。
    双亲委派模型的工作流程是:如果一个类加载器收到了类加载请求,它首先不会自己去尝试加载这个类,而是把这
    个请求委托给父类加载器去完成,每一个层次的类加载器都是如此。因此,所有的加载请求都应当传送到顶层的
    BootStrap加载器中,只有当父加载器反馈无法完成这个加载请求时(在自己搜索范围中没有找到此类),子加载器
    才会尝试自己去加载。
    类加载器的双亲委派模型从JDK1.2引入后被广泛应用于之后几乎所有的Java程序中,但它并不是强制性约束,甚至
    可以破坏双亲委派模型来进行类加载,最典型的就是OSGI技术。
    双亲委派模式对于保证Java程序的稳定运行很重要。有一个显而易见的好处就是Java类随着它的类加载器一起具备
    了一种带有优先级的层次关系。例如java.lang.Object类,它存放在rt.jar中,无论哪一个类加载器要加载这个类,
    最终都是委派给处于顶端的启动类加载器进行加载。因此,Object类在程序的各种类加载器环境中都是同一个类

     

    比较两个类相等的前提:必须是由同一个类加载器加载的前提下才有意义。否则,即使两个类来源于同一个Class
    文件,被同一个虚拟机加载,只要加载他们的类加载器不同,那么这两个类注定不想等。

    动态代理模式

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    interface ISubject { // 核心操作接口
    public void eat(String msg, int num) ; // 吃饭是核心业务
    }
    class RealSubject implements ISubject {
    @Override
    public void eat(String msg ,int num) {
    System.out.println("我要吃 "+num + "分量的 "+msg) ;
    }
    }
    /**
    * 动态代理类
    */
    class ProxySubject implements InvocationHandler {
    // 绑定任意接口的对象,使用Object描述
    private Object target ;
    /**
    * 实现真实对象的绑定处理,同时返回代理对象
    * @param target
    * @return 返回一个代理对象(这个对象是根据接口定义动态创建生成的代理对象)
    */
    public Object bind(Object target) {
    // 保存真实主题对象
    this.target = target ;
    return
    Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfac
    es(),this) ;
    }
    public void preHandle() {
    System.out.println("[ProxySubject] 方法处理前") ;
    }
    public void afterHandle(){
    System.out.println("[ProxySubject] 方法处理后") ;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    this.preHandle() ;
    // 反射调用方法
    Object ret = method.invoke(this.target,args) ;
    this.afterHandle() ;
    return ret;
    }
    }
    public class TestDemo {
    public static void main(String[] args) {
    ISubject subject =(ISubject) new ProxySubject().bind(new RealSubject()) ;
    subject.eat("宫保鸡丁",20) ;
    }
    }
  • 相关阅读:
    洛谷 P1141 01迷宫
    洛谷 p1443
    setw
    Fliptile
    追牛
    Dungeon Master
    vim的一些基本操作
    洛谷 p1309 瑞士轮
    洛谷 p1090 合并果子
    selenium2 WebDriver 在asp.net项目中的应用
  • 原文地址:https://www.cnblogs.com/hetaoyuan/p/11409554.html
Copyright © 2020-2023  润新知