反射

1.反射定义:在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过某种机制来实现对自己行为的描述和监测,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。

2.java类反射中的类

   java类反射所需要的类,分别是:Field、Constructor、Method、Class、Object

 Field类:提供有关类或接口的属性的信息,以及对它的动态访问权限。

Constructor类: 提供关于类的单个构造方法的信息,以及对它的访问权限,此类封装了反射类的构造方法。

Method类:提供关于类或者接口上单独某个方法的信息。此类封装反射类方法的一个类。

Class类:类的实例表示正在运行的java应用程序中的类和接口。

获得反射类的三种方法

  //获取反射类的三种方法
        Class c = null;
        //方法一,调用运行时类本身的.class属性
          c = String.class;
        //方法二  ,通过运行时类的实例获取
        c = new String("").getClass();

       //方法三  Class.forname全包名
           c = Class.forName("java.lang.String");

Field类 

 反射反射

getFields()访问的是 获取可访问类型 的字段

getField()返回指定字段

getDeclaredFields()访问的是所有的字段

getDeclaredField()访问的是某一个已声明的指定字段

建立实体类

package cn.edu.xatu.entity;

public class Student {
    private int id;
    private String name;
    private  char M;
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "name: " + name +" id:"+id+ "M: " +M;
    }
    public Student(String name){
        this.name = name;
        
    }
    public Student(){
        System.out.println("student: 默认构造");
        
    }
    public Student(int id, String name, char m) {
        super();
        this.id = id;
        this.name = name;
        M = m;
    }
    public String speak(String k){
        System.out.println(this.name +k);
        return k;
        
    }
    private int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public char getM() {
        return M;
    }
    public void setM(char m) {
        M = m;
    }

}
 

Field类测试

//获取学生的反射类
         Class student = null;
        try {
            
            student = Class.forName("cn.edu.xatu.entity.Student");
        } catch (Exception e) {
            e.printStackTrace();
        }
//        getFields只能获取到public 类型的
//        Field[] fiedls = student.getFields();
           for (Field field : fiedls) {
            System.out.println("getFields方法获取字段名字"+field.getName());
            System.out.println("getFields方法获取字段类型"+field.getType().getName());
        }
          //获得所有声明的字段,破坏封装
           Field[] f =  student.getDeclaredFields();
            for (Field field : f) {
                //遍历每个字段获取每个字段的名字
             System.out.println("getDeclaredFields获取字段:"+field.getName());
            //获取字段的类型并输出名字    
            System.out.println("getDeclaredFields获取字段类型"+field.getType().getName());
        }
        //获取单个字段对象
            Field f =student.getDeclaredField("name");
            f.setAccessible(true);
            System.out.println(f.getName());
           //获取反射类字段的类型的名字
           System.out.println(f.getType().getName());
           //新建对象
           Student s = new Student("张三");
          //通过反射获取某个实例的某个字段
            String name = (String) f.get(s);
            System.out.println("name:"+name);
//            System.out.println("通过get方法获取name:"+ s.getName());
           
           
         

 反射

 Construceor类

反射

 public void test3(){
        Class c = null;
        try {
            c = Class.forName("cn.edu.xatu.entity.Student");
            //直接通过反射实例得到的是无参构造函数
           Object o =   c.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            
            Constructor f =  c.getConstructor(int.class,String.class,char.class);
            //实例化构造,调用带参构造
                 Object o =f.newInstance(21,"张三",'m');
                 System.out.println(o);
        } catch (Exception e) {
            e.printStackTrace();
        }    
    
    }

运行结果:

反射

Method类 

反射

public void test4(){
        Class c = cn.edu.xatu.entity.Student.class;
         try {
            //通过反射构造实例
            Constructor f =  c.getConstructor(int.class,String.class,char.class);
            Object o =f.newInstance(21,"张三",'m');
            //获取指定参数的方法
            Method m =c.getMethod("speak", String.class);
            //方法调用
            m.invoke(o, "在学习");
        } catch (Exception e) {
            
            e.printStackTrace();
        } 
        
    } 

运行结果:

反射

 反射的一个例子:

创建自己的属性  文件 键、值形式

反射

package cn.edu.xatu.view;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Enumeration;
import java.util.ResourceBundle;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class MyFrame extends JFrame {
    JMenuBar bar = new JMenuBar();
    JMenu menu = new JMenu("功能模块");
        public MyFrame(){    
        bar.add(menu);
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setJMenuBar(bar);
        setSize(800,600);
        setVisible(true);
        //获取资源文件
        ResourceBundle bundle = ResourceBundle.getBundle("function");
        Enumeration<String> keys = bundle.getKeys();
        //获取资源文件的键
        while(keys.hasMoreElements()){
            String key = keys.nextElement();
            System.out.println(key);
            String name =   bundle.getString(key);
            System.out.println(name);
           try {
               //获取该类的反射类
            Class c =     Class.forName(name);
            //对实现execute接口的类进行组装
              Class[] in =  c.getInterfaces();
              for (Class class1 : in) {
                  while("cn.edu.xatu.view.Function".equals(class1.getName())){
                      final  Function o = (Function) c.newInstance();
                      JMenuItem m = new JMenuItem(o.getName());
                         menu.add(m);
                          m.addActionListener(
                                  new ActionListener() {
                                    
                                    @Override
                                    public void actionPerformed(ActionEvent e) {
                                         o.execute(o.getName());
                                        
                                    }
                                  }
                            );
                         break;
                  }
                
            }
            
            
             
        } catch (Exception e) {
            
            e.printStackTrace();
        }
        }
                  
           
    }
    public static void main(String[] args) {
        new MyFrame();
        
    }

}
 

接口函数 

package cn.edu.xatu.view;

public interface Function {
    /**
     * 返回模块名
     * @return
     */
    public String getName();
    /**
     * 获取资源的功能
     */
    public void execute(String name);

}

package cn.edu.xatu.view;

import javax.swing.JOptionPane;

public class WorkPlan implements Function {

    @Override
    public String getName() {
        
        return "工作管理计划";
    }

    @Override
    public void execute(String name) {
         this.getName();
         JOptionPane.showMessageDialog(null,"工作管理计划");
    
    }   

}

package cn.edu.xatu.view;

import javax.swing.JOptionPane;

public class CET implements Function {

    @Override
    public String getName() {
        return "CET管理";
    }

    @Override
    public void execute(String name) {
          this.getName();
          JOptionPane.showMessageDialog(null,"CET管理计划");
    }

}
 

 

运行结果:

反射      反射

 在自己的Frame类里面,读取资源文件,获取配置的全包名,通过发射new出实例,搭建自己所需要的一个功能平台,创建一个接口,根据需求扩展自己的需求,后期可以通过实现接口来增加不同的需求。本来功能的实现需要各个模块子功能的实现,主模块功能才能用,但是通过反射先将主模块功能建立,子功能基于接口实现不同的功能,可以先完成主功能在完成子功能,各自完成各自的,实现了依赖倒置。降低了模块与模块之间的耦合性。