zoukankan      html  css  js  c++  java
  • java反射

     一,先看一下反射的概念:

                 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。

                 反射是java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接。但是反射使用不当会成本很高!

     二,反射机制的作用:

                  1,反编译:.class-->.java

                  2,通过反射机制访问java对象的属性,方法,构造方法等;

     三,在这里先看一下sun为我们提供了那些反射机制中的类:

    java.lang.Class;                
    
    java.lang.reflect.Constructor; java.lang.reflect.Field;        
    
    java.lang.reflect.Method;
    
    java.lang.reflect.Modifier;

    四,具体功能实现:

    //1. 反射机制获取类有三种方法,我们来获取Employee类型
     
    //第一种方法:
        Class c1=Class.forName("Employee");
    //第二种方法:每个类型都有class属性:
        Class c2=Employee.class;
    //第三种方法: 任何一个对象都有getClass方法
        Employee=new Employee();
        Class c3=e.getClass();
    
        
     //2. 创建对象:利用newInstance;
     Class c=Class.forName("Employee");
     Object o=c.newInstance(); //调用了Employee的无参构造函数
     
     
     //3. 获取属性: 分为所有哦的属性和指定的属性
     //a. 获取所有的属性:
     Class c=Class.forName("java.lang.Integer");
     Field[] fs=c.getDeclaredFields();
     //可变长字符串,存储属性
     StringBuffer sb= new StringBuffer();
     //最外边的public定义 
     sb.append(Modifier.toString(c.getModifiers()) + " class"+ c.getSimpleName()+ "{
    ");
     //里面的每一个属性
     for(Field field:fs){
         sb.append("	"); //空格
         sb.append(Modifier.toString(field.getDeclaredFields())+" ");//获得属性的修饰符,例如public,static等等  
         sb.append(field.getType().getSimpleName()+"");//属性的类型的名字
         sb.append(field.getName()+";
    ");//属性的名字+回车 
     }
     sb.append("}");
     System.out.println(sb);
     
     //获取特定的属性
     public static void main(String[] args) throws Exception{
         //获取类
         Class c=Class.forName("User");
         //获取id属性
         Field idF=c.getDeclaredFields("id");
         //实例化这个类赋给o
         Object o=c.newInstance();
         //打破封装
         //使用反射机制可以打破封装性,导致了java对象的属性不安全。
         idF.setAccessible(true);
         //给o对象的id属性赋值"110"  
         idF.set(o,"110");
         System.out.println(idF.get(o));
     }

    方法关键字

    含义

    getDeclaredMethods()

    获取所有的方法

    getReturnType()

    获得方法的放回类型

    getParameterTypes()

    获得方法的传入参数类型

    getDeclaredMethod("方法名",参数类型.class,……)

    获得特定的方法

    构造方法关键字

    含义

    getDeclaredConstructors()

    获取所有的构造方法

    getDeclaredConstructor(参数类型.class,……)

    获取特定的构造方法

    父类和父接口

    含义

    getSuperclass()

    获取某类的父类

    getInterfaces()

    获取某类实现的接口

    //1. 通过一个对象获得完整的包名和类名
    package Reflect;
    class Dome{
        。。。
    }
    
    class hello{
        public static void main(String[] args){
            Demo demo=new Demo();
            System.out.println(demo.getClass().getName());
        }
    }
    
    结果: Reflect.Dome
    
    
    //2. 实例化Class类对象
    packa Reflect;
    class Demo{
        ...
    }
    class hello{
        public static void main(String[] args){
            Class<?> demo1=null;
            Class<?> demo2=null;
            Class<?> demo3=null;
            try{
                demo1=Class.forName("Reflect.Demo");
            }catch(Exception e){
                e.printStackTrace();
            }
            demo2=new Demo().getClass();
            demo3=Demo.class;
            
            System.out.println("类名称   "+demo1.getName());
            System.out.println("类名称   "+demo2.getName());
            System.out.println("类名称   "+demo3.getName());
        }
    }
    
    结果:
        类名称   Reflect.Demo
        类名称   Reflect.Demo
        类名称   Reflect.Demo
    
    
        
    //3. 通过Class实例化其他类的对象
       通过无参构造实例化对象
    package Reflect;
    class Person{
        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 String toString(){
            return "[" +this.name+" "+this.age+"]";
        }
        private String name;
        private int age;
    }
    
    class hello{
        public static void main(String[] args){
            Class<?> demo=null;
            try{
                demo=Class.forName("Reflect.Person");
            }catch(Exception e){
                e.printStackTrace();
            }
            Person per=null;
            try{
                per=(Person) demo.newInstance();
            }catch(InstantiationException e){
                e.printStackTrace();
            }catch(IllegalAccessException e){
                e.printStackTrace();
            }
            per.setName("Rollen");
            per.setAge(20);
            System.out.println(per);
        }
    }
    
    结果:[Rollen  20]
    
    
    但是注意一下,当我们把Person中的默认的无参构造函数取消的时候,比如自己定义只定义一个有参数的构造函数之后,会出现错误:
    比如我定义了一个构造函数:
    public Person(String name, int age) {
            this.age=age;
            this.name=name;
        }
    然后继续运行上面的程序,会出现:
    java.lang.InstantiationException: Reflect.Person
    
        at java.lang.Class.newInstance0(Class.java:340)
    
        at java.lang.Class.newInstance(Class.java:308)
    
        at Reflect.hello.main(hello.java:39)
    
    Exception in thread "main" java.lang.NullPointerException
    
        at Reflect.hello.main(hello.java:47)
    
    所以大家以后再编写使用Class实例化其他类的对象的时候,一定要自己定义无参的构造函数
    
    
    
    //4. 通过Class调用其他类的构造函数
    package Reflect;
    import java.lang.reflect.Constructor;
    class Person{
        public Person(){
            
        }
        public Person(String name){
            this.name=name;
        }
        public Person(int age){
            this.age=age;
        }
        public Person(String name, int age){
            this.age=age;
            this.name=name;
        }
        public String getName(){
            return name;
        }
        public int getAge(){
            return age;
        }
        public String toString(){
            return "["+this.name+""+this.age+"]";
        }
        private String name;
        private int age;
    }
    
    class hello{
        public static void main(String[] args){
            Class<?> demo=null;
            try{
                demo=Class.forName("Reflect.Person");
            }catch(Exception e){
                e.printStackTrace();
            }
            Person per1=null;
            Person per2=null;
            Person per3=null;
            Person per4=null;
            Constructor<?> cons[]=demo.getConstructors();
            try{
                per1=(Person)cons[0].newInstance();
                per2=(Person)cons[1].newInstance("Rollen");
                per3=(Person)cons[2].newInstance(20);
                per4=(Person)cons[3].newInstance("Rollen",20);
            }catch(Exception e){
                e.printStackTrace();
            }
            System.out.println(per1);
            System.out.println(per2);
            System.out.println(per3);
            System.out.println(per4);
        }
    }
    
    结果:
    [null  0]
    [Rollen  0]
    [null  20]
    [Rollen  20]
    
    
    
    //5. 返回一个类实现的接口
    package Reflect;
    interface China{
        public static final String name="Rollen";
        public static int age=20;
        public void sayChina();
        public void sayHello(String name, int age);
    }
    
    class Person implements China{
        public Person(){
            
        }
        public Person(String sex){
            this.sex=sex;
        }
        public String getSex(){
            return sex;
        }
        public void sayChina(){
            System.out.println("hello,china");
        }
        public void sayHello(String name,int age){
            System.out.println(name+" "+age);
        }
        private String sex;
    }
    
    public class hello{
        public static void main(String[] args){
            Class<?> demo=null;
            try{
                demo=Class.getName("Reflect.Person");
            }catch(Exception e){
                e.printStackTrace();
            }
            
            Class<?> intes[]=demo.getInterfaces();
            for(int i=0; i<intes.length;i++){
                System.out.println("实现的接口 "+ inters[i].getName());
            }
        }
    }
    
    结果:   实现的接口   Reflect.China
    
    
    
    
    // 6. 取得其他类中的父类
    class hello{
        public static void main(String[] args){
            Class<?> demo=null;
            try{
                demo=Class.forName("Reflect.Person");
            }catch(Exception e){
                e.printStackTrace();
            }
            
            Class<?> temp=demo.getSuperclass();
            System.out.println("继承的父类为: "+temp.getName());
        }
    }
    结果:继承的父类为:   java.lang.Object
    
    
    //7. 获得其他类中的全部构造函数
    class hello{
        public static void main(String[] args){
            Class<?> demo=null;
            try{
                demo=Class.forName("Reflect.Person");
            }catch(Exception e){
                e.printStackTrace();
            }
            Constructor<?> cons[]=demo.getConstructors();
            for (int i=0; i<cons.length;i++){
                System.out.println("构造方法:"+cons[i]);
            }
        }
    }
    结果:
        构造方法:  public Reflect.Person()
        构造方法:  public Reflect.Person(java.lang.String)
    
    
    
        
    //8. 获取构造函数修饰符
    class hello{
        public static void main(String[] args){
            Clss<?> demo=null;
            try{
                demo=Class.forName("Reflect.Person");
            }catch(Exception e){
                e.printStackTrace();
            }
            Constructor<?> cons[]=demo.getConstructors();
            for(int i=0; i<cons.length;i++){
                Class<?> p[]=cons[i].getParameterTypes();
                System.out.print("构造函数: ");
                int mo=cons[i].getModifiers();
                System.out.print(Modifier.toString(mo)+"");
                System.out.print(cons[i].getName());
                System.out.print("(");
                for(int j=0;j<length;j++){
                    System.out.print(p[j].getName()+" arg"+i);
                    if(j<p.length-1){
                        System.out.print(",");
                    }
                }
                System.out.println("){}");
            }
        }
    }
    
    结果:
    构造方法:  public Reflect.Person(){}
    构造方法:  public Reflect.Person(java.lang.String arg1){}
    
    
    
    //9. 取得类的全部属性
    class hello{
        public static void main(String[] args){
            Class<?> demo= null;
            try{
                demo=Class.forName("Reflect.Person");
            }catch(Exception e){
                e.printStackTrace();
            }
            System.out.println("=====本类属性=====");
            Field[] field=demo.getDeclaredFields();
            for(int i=0;i<field.length;i++){
                //权限修饰符
                int mo=field[i].getModifiers();
                String priv=Modifier.toString(mo);
                //属性类型
                Class<?> type=field[i].getType();
                System.out.println(priv+" "+type.getName()+""+field[i].getName()+";");
            }
            System.out.println("=====实现的接口或父类的属性=====");
            //取得实现的接口或父类的属性
            Field[] field1=demo.getFields();
            for(int j=0;i<field1.length;j++){
                //权限修饰符
                int mo=filed1[j].getModifiers();
                String priv=Modifier.toString(mo);
                //属性类型
                Class<?> type=filed1[j].getType();
                System.out.println(priv+""+type.getName()+""+field1[j].getName()+";");
            }
        }
    }
    
    结果:
    ===============本类属性========================
    private java.lang.String sex;
    ===============实现的接口或者父类的属性========================
    public static final java.lang.String name;
    public static final int age;
    
    
    
    //10.调用其他类中的方法
    class hello{
        public static void main(String[] args){
            Class<?> demo=null;
            try{
                demo=Clss.forName("Reflect.Person");
            }catch(Exception e){
                e.printStackTrace();
            }
            try{
                Method method=demo.getMethod("sayChina");
                method.invoke(demo.newInstance());
                
                method=demo.getMethod("sayChina",String.class,int.class);
                method.invoke(demo.newInstance(),"Rollen",20);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
    结果:
    hello ,china
    Rollen  20
    
    
    //11. 调用其他类的set和get方法
    class hello{
        public static void main(String[] args){
            Class<?> demo=null;
            Object obj=null;
            try{
                demo=Class.forName("Reflect.Person");
            }catch(Exception e){
                e.printStackTrace();
            }
            try{
                obj=demo.newInstance();
            }catch(Exception e){
                e.printStackTrace();
            }
            setter(obj,"Sex","男",String.class);
            getter(obj,"Sex");
        }
        
        /**
         * @param obj
         *            操作的对象
         * @param att
         *            操作的属性
         * */
        public static void getter(Object obj, String att) {
            try {
                Method method = obj.getClass().getMethod("get" + att);
                System.out.println(method.invoke(obj));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
     
        /**
         * @param obj
         *            操作的对象
         * @param att
         *            操作的属性
         * @param value
         *            设置的值
         * @param type
         *            参数的属性
         * */
        public static void setter(Object obj, String att, Object value,
                Class<?> type) {
            try {
                Method method = obj.getClass().getMethod("set" + att, type);
                method.invoke(obj, value);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }    
    }
    结果:   男
    
    
    
    //12. 1)通过反射取得并修改数组的信息:
    import java.lang.reflect.*;
    class hello{
        public static void main(String[] args){
            int[] temp={1,2,3,4,5};
            Class<?> demo=temp.getClass().getComponentType();
            System.out.println("数组类型: "+demo.getName());
            System.out.println("数组长度: "+Array.getLength((temp));
            System.out.println("数组的第一个元素:"Array.get(temp,0));
            Array.set(temp,0,100);
            System.out.println("修改之后数组第一个元素为:"+Array.get(temp,0));
        }
    }
    结果:
    数组类型: int
    数组长度  5
    数组的第一个元素: 1
    修改之后数组第一个元素为: 100
    
    
    
    
    //12. 2)反射修改数组大小
    class hello{
        public static void main(String[] args) {
            int[] temp={1,2,3,4,5,6,7,8,9};
            int[] newTemp=(int[])arrayInc(temp,15);
            print(newTemp);
            System.out.println("=====================");
            String[] atr={"a","b","c"};
            String[] str1=(String[])arrayInc(atr,8);
            print(str1);
        }
         
        /**
         * 修改数组大小
         * */
        public static Object arrayInc(Object obj,int len){
            Class<?>arr=obj.getClass().getComponentType();
            Object newArr=Array.newInstance(arr, len);
            int co=Array.getLength(obj);
            System.arraycopy(obj, 0, newArr, 0, co);
            return newArr;
        }
        /**
         * 打印
         * */
        public static void print(Object obj){
            Class<?>c=obj.getClass();
            if(!c.isArray()){
                return;
            }
            System.out.println("数组长度为: "+Array.getLength(obj));
            for (int i = 0; i < Array.getLength(obj); i++) {
                System.out.print(Array.get(obj, i)+" ");
            }
        }
    }
    结果:
    数组长度为: 15
    1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 =====================
    数组长度为: 8
    a b c null null null null null
  • 相关阅读:
    完全开源Android网络框架 — 基于JAVA原生的HTTP框架
    博客园—Android客户端
    撸一个Android高性能日历控件,高仿魅族
    Android开发登陆博客园的正确方式
    基于pthread的线程池实现
    重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印
    重复造轮子系列——基于Ocelot实现类似支付宝接口模式的网关
    零基础ASP.NET Core WebAPI团队协作开发
    零基础ASP.NET Core MVC插件式开发
    jquery对下拉框的操作
  • 原文地址:https://www.cnblogs.com/zxqstrong/p/5545314.html
Copyright © 2011-2022 走看看