欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

反射(Reflaction)初探

程序员文章站 2022-06-06 23:29:33
...

        昨天,在蓝杰很多同学一起讨论了反射的东西。大家你一言我一语就把我给整蒙了,一个简简单单的反射,弄得我稀里糊涂的,回寝后就在网上搜了两篇文章,看了别人写的文章,总算是有点头绪了。于是就自己写了一个小程序,测试了一下动态装载的东西。先来解释一下反射的概念,然后贴代码,看结果。

       Java 反射机制是指Java程序可以在执行期载入,探知,使用编译期间完全未知的classes.这句话可能有点难以理解,我们可以通过一个例子来看。在 Java程序中我们经常会用到这样一条语句来创建一个对象。Date date = new Date();在这条语句中date的类型(Java.util.Date)在编译时已经确定。那么,有没有办法使我们把对象类型的确定时间由编译转到运行,答案是肯定的。这就是Java反射机制所提供的便利。而且它不单单可以生成对象还可以获取Field,对Field设值,及调用方法等。

       谈及Java反射机制就一定要知道一个名为“Class”的类,它是Java反射机制的基础。“Class”和其它类一样继承于Object类,它的实例对象用来描述Java运行时的一种类型,接口,或者原始类型(比如 int.“Class”的实例要由JVM创建,它没有公用的构造方法。下面我们来看一下如何获得"Class"类实例。

主要有三种方法。

  一,通过Class类的静态方法forName获取。Class cla = Class.forName("java.lang.String");

  二,通过.Type.class属性获得。Class cla = String.class;Class cla1 = int.Type;

  三,通过实例变量的getClass方法获得。String s = ""; Class cla = s.getClass();

  如上所示实例对象cla就是对String类型的描述,通过它我们就可以创建一个String实例,并调用其中的方法。

 

      上面的某几段来自百度文库上的一片文章,写的很棒!地址点这里

 

       下面是我写的一个例子,代码的意图是:

       Computer接口:含一个方法,测试是否能开机

       Dell类:继承了Computer接口,并加入了一些Dell电脑的信息

       Lenove类:继承了Computer接口,并加入了一些Lenove电脑的信息

       Apple类:继承了Computer接口,并加入了一些Apple电脑的信息

       Selecter类:用窗口实现了一些东东

 

public interface Computer {
	//在这个接口中定义方法
	public String startScreen();//开机的方法
	
}

 

public class Dell implements Computer {

	private String operatingSystem = "Windows7";
	private int prize = 4500;
	private int hardMemory = 320;
	private int Memory = 2;

	public String startScreen() {
		return "Dell is OK!";
	}
}

 

public class Apple implements Computer{

	private String operatingSystem = "IOS";
	private int prize = 7000;
	private int hardMemory = 500;
	private int Memory = 4;
	@Override
	public String startScreen() {
		return "Apple is OK!";
	}
}

 

public class Lenove implements Computer {

	private String operatingSystem = "Windows XP";
	private int prize = 5000;
	private int hardMemory = 500;
	private int Memory = 2;
	@Override
	public String startScreen() {
		return "Lenove is OK!";
	}
}

 

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;

public class Selecter extends JFrame {

	JTextArea area;

	private void initFrame() {
		this.setName("电脑信息查询");
		this.setLayout(new FlowLayout());
		this.setSize(new Dimension(340, 400));
		this.setLocationRelativeTo(null);
		this.setDefaultCloseOperation(3);
		JLabel lable = new JLabel("查询的电脑:");
		final JTextField text = new JTextField(13);
		JButton button1 = new JButton("查询");
		JButton button2 = new JButton("测试");
		area = new JTextArea();
		JScrollPane scrollpane = new JScrollPane(area);
		scrollpane.setPreferredSize(new Dimension(290, 290));
		this.add(lable);
		this.add(text);
		this.add(button1);
		this.add(button2);
		this.add(scrollpane);
		this.setVisible(true);// 设置窗体可见

		// 给按钮1添加监听器
		button1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String text1 = text.getText();
				getDescription(text1);
			}
		});
		// 给按钮2添加监听器
		button2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String text2 = text.getText();
				Computer com = (Computer) getComputer(text2);
				testComputer(com, "startScreen");
			}
		});

	}

	// 得到所查询电脑的详细信息
	public void getDescription(String type) {
		try {
			Class cla = Class.forName(type);
			// 生成一个实例对象,在编译时我们并不知道obj是什么类型
			Object obj = cla.newInstance();
			// 获得type类型所有已定义类变量及方法。
			Field[] fileds = cla.getDeclaredFields();
			area.append(cla.getSimpleName()+"电脑的详细信息是:\n");

			for (int i = 0; i < fileds.length; i++) {
				fileds[i].setAccessible(true);
				// 输出类变量的定义及obj实例中对应的值
				area.append(fileds[i].getName() + ":" + fileds[i].get(obj) + "\n");
			}
			area.append("\n");
		} catch (Exception e) {
			area.append("对不起,没有这种电脑的信息!\n\n");
		}
	}

	// 使用电脑的某个功能
	public void testComputer(Object obj, String function) {
		try {
			Class cla = obj.getClass();
			// 获得cla类中定义的无参方法。
			Method m = cla.getMethod(function, null);
			// 调用obj中名为function的无参方法。
			String aa= (String)m.invoke(obj, null);
			area.append(aa+"\n\n");
		} catch (Exception e) {}
	}

	// 拿电脑给顾客
	public Object getComputer(String type) {
		try {
			Class cla = Class.forName(type);
			Object obj = cla.newInstance();
			return obj;
		} catch (Exception e) {
			area.append("对不起,没有这种电脑的信息!\n\n");
			return null;
		}
	}

	public static void main(String[] args) {

		/*************** 以下几句是优化窗体界面的方法 ***************************/
		JFrame.setDefaultLookAndFeelDecorated(true); // 加上此语句连同窗体外框也改变
		JDialog.setDefaultLookAndFeelDecorated(true); // 加上此语句会使弹出的对话框也改变
		try {
			UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
		} catch (Exception e) {
			e.printStackTrace();
		}
		/*************** 以上几句是优化窗体界面的方法 ***************************/

		Selecter selecter = new Selecter();
		selecter.initFrame();

	}

}

 

     当我输入使用控制台编译Selecter后,三个电脑类还没有被编译。

 

反射(Reflaction)初探
            
    
    博客分类: Java学习笔记   反射(Reflaction)初探
            
    
    博客分类: Java学习笔记  

 

       弹出的窗体如下,当我输入Dell时,因为Dell类此时未被编译,所以没有.class文件,显示没有此电脑信息。

       当我编译后,再次点击查询的时候就可以了,这个时候主程序是没有退出的,也就是说,这个类是被动态加载到程序中的,这是使用反射实现的。

 

反射(Reflaction)初探
            
    
    博客分类: Java学习笔记   反射(Reflaction)初探
            
    
    博客分类: Java学习笔记  
反射(Reflaction)初探
            
    
    博客分类: Java学习笔记   反射(Reflaction)初探
            
    
    博客分类: Java学习笔记  
 

 大概的就是这些吧,要休息了,如有不完善赶明儿个再补充!

—2013年1月25日凌晨写于刘洋寝室

 

  • 反射(Reflaction)初探
            
    
    博客分类: Java学习笔记  
  • 描述: 写好的几个类
  • 大小: 85.6 KB
  • 反射(Reflaction)初探
            
    
    博客分类: Java学习笔记  
  • 描述: 编译Selecter.java
  • 大小: 68 KB
  • 反射(Reflaction)初探
            
    
    博客分类: Java学习笔记  
  • 描述: 没有编译Dell前的窗体
  • 大小: 29.9 KB
  • 反射(Reflaction)初探
            
    
    博客分类: Java学习笔记  
  • 描述: 编译Dell后再次点击查询
  • 大小: 42.3 KB
  • 反射(Reflaction)初探
            
    
    博客分类: Java学习笔记  
  • 描述: 编译Dell和Apple类
  • 大小: 50.4 KB
  • 反射(Reflaction)初探
            
    
    博客分类: Java学习笔记  
  • 描述: 编译后Apple也可以被查询了
  • 大小: 40.4 KB