• 3.6 java基础总结①反射


    反射

    反射是Java的灵魂
    反射是Java动态性最佳体现
    动态性是在运行时去改变或绑定编译时确定的效果

    Java不是动态语言,只有一定的动态性
    Java利用反射实现动态性:运行时探究和使用编译时未知的类

    类的加载机制
    Class类(类模板)
    加载 → 验证 → 准备 → 解析 → 初始化(静态属性初始化)

    验证准备解析是连接阶段

    反射通过名称来得到对象(类,属性,方法)
    一句话:运行时探究和使用编译时未知的类

    步骤
    一、获得想要操作的 java.lang.Class对象
    二、调用 getDeclaredMethods方法(属性方法行为)
    三、使用reflection API来操作这些信息

    属性:get/set ①②
    构造:产生实例对象①②
    方法:调用 ①②

    属性①
    getDeclareFields()全部
    getFields 公共

    getDeclareFields() 一个
    getFields 一个

    其他同理

     1 package com.lovo.bean;
     2 
     3 import java.io.Serializable;
     4 
     5 /**
     6  * Date: 2016-3-4-上午10:26:23
     7  * Class_name: Student.java
     8  * Package_name: com.lovo.bean
     9  * Author: ZhangYue
    10  * Description: 
    11  */
    12 public class Student extends Object implements Serializable,Runnable{
    13     
    14     private String name;
    15     
    16     protected int age;
    17     
    18     boolean gender;
    19     
    20     public float height;
    21     
    22     public Student(){
    23         
    24     }
    25     
    26     public Student(String name){
    27         this.name = name;
    28     }
    29     
    30     private Student(String name,int age){
    31         this.name = name;
    32         this.age = age;
    33     }
    34     
    35     public void study(int num){
    36         for(int i = 0; i < num; i++){
    37             System.out.println("Good Good Study,Day Day Up!");
    38         }
    39     }
    40     
    41     private void answer(){
    42         System.out.println("Open Yellow Gun!");
    43     }
    44 
    45     @Override
    46     public void run() {
    47         // TODO Auto-generated method stub
    48         System.out.println("奔跑吧,线程!");
    49     }
    50     
    51     
    52 }
    Student
      1 package com.lovo.test;
      2 
      3 import java.lang.reflect.Constructor;
      4 import java.lang.reflect.Field;
      5 import java.lang.reflect.InvocationTargetException;
      6 import java.lang.reflect.Method;
      7 import java.lang.reflect.Modifier;
      8 import com.lovo.bean.Student;
      9 
     10 /**
     11  * Date: 2016-3-4-上午10:29:36
     12  * Class_name: TestMain.java
     13  * Package_name: com.lovo.test
     14  * Author: ZhangYue
     15  * Description: 
     16  */
     17 public class ReflectMain {
     18 
     19     /**
     20      * @param args
     21      */
     22     public static void main(String[] args) {
     23         // TODO Auto-generated method stub
     24         //反射的使用:在运行时探究和使用编译时未知的类
     25         /*
     26          * 1、获取类的Class对象(其实所有的类型都有Class对象)
     27          */
     28         //1-1、根据一个实例对象(排除了基本数据类型),产生Class对象---动态性最低
     29         Student stu = new Student();
     30         Class stuClass = stu.getClass();//来自于Object的方法
     31         int[] array = new int[5];
     32         Class arrayClass = array.getClass();
     33         
     34         //1-2、根据类型名,获取Class对象---动态性低
     35         Class stuClass1 = Student.class;
     36         Class arrayClass1 = int[].class;
     37         Class intClass = int.class;//基本数据类型.class的方式是JDK1.5以后提供的
     38         Class voidClass = void.class;
     39         Class intClass1 = Integer.TYPE;//JDK1.5以前,使用基本数据类型对应的包装类.TYPE
     40         
     41         //1-3、根据类的字符串全类名,获取Class对象---动态性最高
     42         Class stuClass2 = null;        
     43         try {
     44             stuClass2 = Class.forName("com.lovo.bean.Student");//字符串全类名完全可以从程序外部输入
     45         } catch (ClassNotFoundException e) {
     46             // TODO Auto-generated catch block
     47             e.printStackTrace();
     48         }
     49         
     50         
     51         /*
     52          * 2、探究Class对象中类的信息
     53          */
     54         //2-1、探究类的声明部分
     55         System.out.println("package " + stuClass.getPackage().getName() + ";");//得到包名
     56         String allName = stuClass.getName();//得到类全名
     57         String simpleName = stuClass.getSimpleName();//得到类的简单名
     58         int classMod = stuClass.getModifiers();//得到类的修饰符
     59         String classModStr = Modifier.toString(classMod);//得到修饰符的字符串形式
     60         String superClassName = stuClass.getSuperclass().getName();//得到父类的Class对象
     61         Class[] allInter = stuClass.getInterfaces();//得到所有接口的Class对象
     62         String allInterNames = "";
     63         for(int i = 0; i < allInter.length; i++){
     64             allInterNames += allInter[i].getName();
     65             if(i != allInter.length - 1){
     66                 allInterNames += ",";
     67             }
     68         }
     69         
     70         System.out.println(classModStr + " class " + simpleName + 
     71                 " extends " + superClassName + " implements " + allInterNames + "{");
     72         
     73         System.out.println("//属性");
     74         //2-2、属性的探究
     75         Field[] allFields = stuClass.getDeclaredFields();//获取所有的属性
     76         Field[] allPubicFields = stuClass.getFields();//获取所有的公共属性
     77         //探究指定的属性
     78         try {
     79             Field field = stuClass.getDeclaredField("name");//根据属性名,返回指定的属性
     80             Field publicField = stuClass.getField("height");//根据属性名,返回指定的公共属性
     81         } catch (NoSuchFieldException e) {
     82             // TODO Auto-generated catch block
     83             e.printStackTrace();
     84         } catch (SecurityException e) {
     85             // TODO Auto-generated catch block
     86             e.printStackTrace();
     87         }
     88         
     89         for(Field f : allFields){
     90             String fieldMod = Modifier.toString(f.getModifiers());//得到属性的修饰符
     91             String fieldTypeStr = f.getType().getName();//得到属性的类型名
     92             String fieldName = f.getName();//得到属性的名字
     93             
     94             System.out.println("	" + fieldMod + " " + fieldTypeStr + " " + fieldName + ";");
     95         }
     96         
     97         System.out.println();
     98         System.out.println("//构造");
     99         
    100         //2-3、探究构造方法
    101         Constructor[] allCons = stuClass.getDeclaredConstructors();//得到所有声明的构造
    102         Constructor[] allPublicCons = stuClass.getConstructors();//得到所有公共的构造
    103         try {
    104             Constructor con = stuClass.getDeclaredConstructor(String.class,int.class);//得到指定的构造
    105             Constructor publicCon = stuClass.getConstructor();//得到指定的公共构造
    106         } catch (NoSuchMethodException e) {
    107             // TODO Auto-generated catch block
    108             e.printStackTrace();
    109         } catch (SecurityException e) {
    110             // TODO Auto-generated catch block
    111             e.printStackTrace();
    112         }
    113         
    114         for(Constructor c : allCons){
    115             String conModStr = Modifier.toString(c.getModifiers());//得到构造的修饰符
    116             String conName = c.getName();//得到构造方法的名字
    117             Class[] parametersClassArray = c.getParameterTypes(); //得到所有的参数
    118             String paramStr = "";
    119             for(Class paramClass : parametersClassArray){
    120                 paramStr += paramClass.getSimpleName() + ",";
    121             }
    122             if(parametersClassArray.length != 0){
    123                 paramStr = paramStr.substring(0,paramStr.length()-1);
    124             }
    125             System.out.println("	" + conModStr + " " + conName + "(" + paramStr + ")");
    126         }
    127         
    128         System.out.println();
    129         System.out.println("//方法");
    130         
    131         //2-4、探究方法
    132         Method[] allMethods = stuClass.getDeclaredMethods();//得到所有声明的方法
    133         Method[] allPublicMethods = stuClass.getMethods();//得到所有的公共方法
    134         
    135         try {
    136             Method method = stuClass.getDeclaredMethod("answer");//得到指定的声明方法
    137             Method publicMethod = stuClass.getMethod("study",int.class);//得到指定的公共方法
    138         } catch (NoSuchMethodException e) {
    139             // TODO Auto-generated catch block
    140             e.printStackTrace();
    141         } catch (SecurityException e) {
    142             // TODO Auto-generated catch block
    143             e.printStackTrace();
    144         }
    145         
    146         for(Method m : allMethods){
    147             String methodMod = Modifier.toString(m.getModifiers());
    148             String returnStr = m.getReturnType().getName();
    149             String methodName = m.getName();
    150             String paramStr = "";
    151             Class[] params = m.getParameterTypes();
    152             for(int i = 0; i < params.length; i++){
    153                 paramStr += params[i].getName();
    154                 if(i != params.length - 1){
    155                     paramStr += ",";
    156                 }
    157             }
    158             
    159             System.out.println("	" + methodMod + " " + returnStr + " " 
    160                     + methodName + "(" + paramStr + ")");
    161         }        
    162         System.out.println("}");
    163         
    164         
    165         /*
    166          * 3、使用反射获取的信息
    167          */
    168         //3-1、根据反射产生对象
    169         //3-1-1、通过Class对象获取Constructor对象,然后产生实例对象(好处:可以调用任意符合访问修饰符的构造方法;坏处:代码太多)
    170 //        Constructor con = null;
    171 //        try {
    172 //            con = stuClass.getConstructor(String.class);
    173 //        } catch (NoSuchMethodException e) {
    174 //            // TODO Auto-generated catch block
    175 //            e.printStackTrace();
    176 //        } catch (SecurityException e) {
    177 //            // TODO Auto-generated catch block
    178 //            e.printStackTrace();
    179 //        }
    180 //        
    181 //        try {
    182 //            Student stu1 = (Student)con.newInstance("zhang3");//使用Constructor的newInstance方法产生对象
    183 //            Student stu2 = (Student)con.newInstance("zhang3");
    184 //            System.out.println(stu1);
    185 //            System.out.println(stu2);
    186 //        } catch (InstantiationException e) {
    187 //            // TODO Auto-generated catch block
    188 //            e.printStackTrace();
    189 //        } catch (IllegalAccessException e) {
    190 //            // TODO Auto-generated catch block
    191 //            e.printStackTrace();
    192 //        } catch (IllegalArgumentException e) {
    193 //            // TODO Auto-generated catch block
    194 //            e.printStackTrace();
    195 //        } catch (InvocationTargetException e) {
    196 //            // TODO Auto-generated catch block
    197 //            e.printStackTrace();
    198 //        }
    199         //3-1-2、直接通过Class对象产生实例对象(好处:代码少;坏处:只能调用到公共无参构造)
    200 //        try {
    201 //            Student stu1 = (Student)stuClass.newInstance();
    202 //            System.out.println(stu1);
    203 //        } catch (InstantiationException e) {
    204 //            // TODO Auto-generated catch block
    205 //            e.printStackTrace();
    206 //        } catch (IllegalAccessException e) {
    207 //            // TODO Auto-generated catch block
    208 //            e.printStackTrace();
    209 //        }
    210         
    211         //3-2、根据反射调用方法
    212 //        try {
    213 //            Method m = stuClass.getMethod("study",int.class);
    214 //            m.invoke(null,4);//使用Method对象提供的invoke方法,调用Method所代表的方法
    215 //        } catch (NoSuchMethodException e) {
    216 //            // TODO Auto-generated catch block
    217 //            e.printStackTrace();
    218 //        } catch (SecurityException e) {
    219 //            // TODO Auto-generated catch block
    220 //            e.printStackTrace();
    221 //        } catch (IllegalAccessException e) {
    222 //            // TODO Auto-generated catch block
    223 //            e.printStackTrace();
    224 //        } catch (IllegalArgumentException e) {
    225 //            // TODO Auto-generated catch block
    226 //            e.printStackTrace();
    227 //        } catch (InvocationTargetException e) {
    228 //            // TODO Auto-generated catch block
    229 //            e.printStackTrace();
    230 //        }
    231         
    232         //3-3、根据反射操作属性
    233         try {
    234             Field f = stuClass.getField("height");
    235             f.set(stu,1.8f);//用set方法赋值
    236             System.out.println(f.get(stu));//用get方法取值
    237             
    238         } catch (NoSuchFieldException e) {
    239             // TODO Auto-generated catch block
    240             e.printStackTrace();
    241         } catch (SecurityException e) {
    242             // TODO Auto-generated catch block
    243             e.printStackTrace();
    244         } catch (IllegalArgumentException e) {
    245             // TODO Auto-generated catch block
    246             e.printStackTrace();
    247         } catch (IllegalAccessException e) {
    248             // TODO Auto-generated catch block
    249             e.printStackTrace();
    250         }
    251         
    252     }
    253 
    254 }
    ReflectMain
  • 相关阅读:
    拯救祭天的程序员——事件溯源模式
    啥?SynchronousQueue和钟点房一个道理
    程序员应该掌握的一些 Linux 命令
    Linux 环境下使用 sqlplus 访问远程 Oracle 数据库
    我对鸿蒙OS的一些看法
    我对技术潮流的一些看法
    git merge --ff/--no-ff/--ff-only 三种选项参数的区别
    go语言的初体验
    完全使用 VSCode 开发的心得和体会
    重复代码的克星,高效工具 VSCode snippets 的使用指南
  • 原文地址:https://www.cnblogs.com/chenyuanqiu2008/p/5252035.html
Copyright © 2020-2023  润新知