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

    反射

    java的动态机制,用于在运行期间检查对象的类型,检查对象的类结构(属性,方法等),还可以动态加载类,动态创建对象,动态访问属性和方法等。

    反射是Java 的API.

    public void print(Object obj){
          //动态反射API,动态检查obj引用的对象类型
           Class cls=obj.getClass();
           System.out.println(obj);
    }

    经典面试题目:Eclipse中快捷菜单用了什么技术实现的?
    答案:反射技术,反射API

    解耦
    解除耦合性:降低/解除 两端代码(两个组件)之间的耦合关系
    利用反射API,可以实现一个组件与未来的一个组件的松散耦合.甚至可以不在不知道
    类名不知道方法名的情况下实现调用关系

    反射的功能

    1.动态加载类
    2.动态创建对象
    3.动态调用属性和方法

    public class ReflectDemo01 {
    
        public static void main(String[] args) {
            print(1);
            print("1");
            print('1');
        }
        
        public static void print(Object obj){
            //动态检查obj对象的类型
            //getClass方法在Object类上定义,被所有对象继承,全部对象都有的方法
            Class cls=obj.getClass();
            /*
             * Class提供了更加详尽的类型详细信息
             * 检查方法:检查属性,检查方法,检查构造器.....
             * 动态检查Integer等类型的属性
             */
            //Declared:声明的  Field:字段,属性
            System.out.println("属性:------------------------");
            Field[] fields=cls.getDeclaredFields();
            for(Field field:fields){
                System.out.println(field);
            }
            System.out.println("方法:------------------------");
            //获取当前类型上声明的所有方法信息
            Method[] methods=cls.getDeclaredMethods();
            for(Method method:methods){
                System.out.println(method);
            }
            System.out.println(cls);
            System.out.println(obj);
        }
    
    }

    利用反射API动态加载类到方法区:

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    
            Scanner in=new Scanner(System.in);
            System.out.println("输入类名:");
            String className=in.nextLine();
            /*
             * 动态加载类到方法区,如果类名错误则抛出“类没有找到的运行异常”
             */
            Class cls=Class.forName(className);
            System.out.println(cls);
            //进一步检查类的详细信息....
            Field[] file=cls.getDeclaredFields();
            for(Field f:file){
                System.out.println(f);
            }
            System.out.println("-----------------------");
            Method[] method=cls.getMethods();
            for(Method m:method){
                System.out.println(m);
            }
            /**
             * 利用反射API动态创建对象
             */
            Object obj=cls.newInstance();
            System.out.println(obj);
    
        }
    
    }

    执行一个类的全部以test为开头的方法,这些方法都是非静态方法,方法没有返回值,没有参数

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            
           //动态加载类
            Scanner in=new Scanner(System.in);
            System.out.println("输入类名:");
            String className=in.nextLine();
            Class cls=Class.forName(className);
            //动态创建对象
            Object obj=cls.newInstance();
            //动态检查类中的全部方法信息
            Method [] methods=cls.getDeclaredMethods();
            for(Method m:methods){
                //System.out.println(m);
                /*
                 * method 代表一个方法的相关信息
                 * method.getName()  返回方法名
                 */
                String name=m.getName();
                //System.out.println(name);
                if(name.startsWith("test")){
                    System.out.println("test开头:"+m);
                    /*
                     * Access 访问
                     * Accessble可访问
                     * 可以打破封装,访问不可见的方法
                     */
                    m.setAccessible(true);
                    
                    /*
                     * method.invoke() 方法用于在对象上调用(invoke)当前
                     * method对应的方法,必须传递包含方法的对象作为参数。
                     */
                    Object val=m.invoke(obj,1);
                    System.out.println(val);
                }
            }
        }

    利用反射动态调用方法:

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            
            Scanner in=new Scanner(System.in);
            System.out.println("输入类名:");
            String className=in.nextLine();
            System.out.println("方法名:");
            String methodName=in.nextLine();
            System.out.println("参数类型:");
            String typeName=in.nextLine();
            System.out.println("参数值:");
            String paramValue=in.nextLine();
            
            //动态加载类
            Class cls=Class.forName(className);
            //参数类型转换
            Class type=null;  //方法的参数类型
            Object param=null;//调用方法时的实际参数
            if(typeName.equals("int")){
                //java中int的类型表示为:int.class
                type=int.class;
                param=Integer.parseInt(paramValue);
            }else if(typeName.equals("double")){
                type=double.class;
                param=Double.parseDouble(paramValue);
            }else if(typeName.equals("String")){
                type=String.class;
                param=paramValue;
            }
            //找到一个被执行的方法信息
            Method method=cls.getDeclaredMethod(methodName,type);
            //method.setAccessible(true);
            System.out.println(method);
            //动态创建对象
            Object obj=cls.newInstance();
            /*
             * 执行方法
             * obj代表包含方法的对象
             * param代表执行方法的时候的实际参数
             * param的数据类型要与type一致
            */
            Object value=method.invoke(obj, param);
            System.out.print(value);
            
            
    
        }

    利用反射获取属性的值:

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {
            Scanner in=new Scanner(System.in);
            System.out.println("类名:");
            String className=in.nextLine();
            System.out.println("属性名:");
            String name=in.nextLine();
            Class cls=Class.forName(className);
            //动态创建对象
            Object obj=cls.newInstance();
            //在类上查找指定的类信息
            Field fld=cls.getDeclaredField(name);
            //获取对象obj上的fld属性信息
            Object value=fld.get(obj);
            //输出属性的值
            System.out.println(value);
    
        }

    获取字符串的char[] value属性
    因为属性value是私有的,所以采用反射API访问:

    public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
            String s="落霞与孤鹜齐飞,秋水共长天一色。";
            //找到属性信息
            Class cls=String.class;
            Field fld=cls.getDeclaredField("value");
            fld.setAccessible(true);
            char [] chs=(char[])fld.get(s);
            for(char c:chs){
                System.out.println(c);
            }
    //        chs[1]='好';
    //        System.out.println(s);
                    
        }

    运行结果:

    利用反射API动态设置对象的属性:

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
            Scanner in=new Scanner(System.in);
            System.out.println("类名:");
            String className=in.nextLine();
            System.out.println("属性:");
            String name=in.nextLine();
            System.out.println("值:");
            String value=in.nextLine();
            Class cls=Class.forName(className);
            Field fld=cls.getDeclaredField(name);
            Object obj=cls.newInstance();
            //设置obj对象的fld属性值为value
            fld.set(obj,value);
            System.out.println(obj);
    
        }

    demo:

    public class TestCase {
    
        public void testHello(){
            System.out.println("hello world!");
        }
        
        private void testKitty(){
            System.out.println("hello kitty!");
        }
        
        public void demo(){
            System.out.println("demo");
        }
    }
    public class Foo {
        public int age=3;
        private String name;
        private int salary;
        private String gender;
        public Foo(){
            
        }
        @Override
        public String toString() {
            return "Foo [age=" + age + ", name=" + name + ", salary=" + salary + ", gender=" + gender + "]";
        }
        public Foo(int age, String name, int salary, String gender) {
            super();
            this.age = age;
            this.name = name;
            this.salary = salary;
            this.gender = gender;
        }
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + age;
            result = prime * result + ((gender == null) ? 0 : gender.hashCode());
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            result = prime * result + salary;
            return result;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Foo other = (Foo) obj;
            if (age != other.age)
                return false;
            if (gender == null) {
                if (other.gender != null)
                    return false;
            } else if (!gender.equals(other.gender))
                return false;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            if (salary != other.salary)
                return false;
            return true;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getSalary() {
            return salary;
        }
        public void setSalary(int salary) {
            this.salary = salary;
        }
        public String getGender() {
            return gender;
        }
        public void setGender(String gender) {
            this.gender = gender;
        }
        
    
    }
    public class Goo {
         private int test(int a){
             return a+1;
          }
          public String demo(String s){
             return s+"";
          }
          public double demo(double d){
             return d+1;
          }
    }
    public class Person {
    
        String name;
        
        String sex;
    
        @Override
        public String toString() {
            return "Person [name=" + name + ", sex=" + sex + "]";
        }
        
    }
  • 相关阅读:
    数据库中的 索引
    JQuery中ajax请求
    如何优化广告,提高点击率
    常用的正则表达式
    全栈工程师之路中级篇之小程序开发前言
    ionic入门教程第四课使用$controllerProvider按需加载controller
    全栈工程师之路中级篇之小程序开发第一章第一节注册小程序
    ionic入门教程第三课在项目中使用requirejs分离controller文件和server文件
    ionic入门教程第五课举例子说明异步回调$q及$q在项目中的用法
    求两个整数的最大公约数和最小公倍数
  • 原文地址:https://www.cnblogs.com/jyy599/p/12093893.html
Copyright © 2011-2022 走看看