java中【反射(Reflect)】的常见应用场景

简介:

总结于imooc课程:     http://www.imooc.com/learn/199  

本文通过几个简单的例子,介绍Class类的使用,方法和成员变量的反射,以及通过反射了解集合泛型的本质等知识。

1.Class类的使用

/**
 * 使用java.lang.Class类动态加载一个类,编译时不对类是否存在以及对错进行检查,运行时检查
 */
public class OfficeBetter {
	public static void main(String[] args) {
		args = new String[1];
		Scanner input = new Scanner(System.in);
		args[0] = input.next();
		try {
			Class<?> c = Class.forName("动态加载."+args[0]);
			IOfficeStart officeStart = (IOfficeStart)c.newInstance();
			officeStart.start();
		} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		} finally{
			input.close();
		}

	}

}

//office功能接口
public interface IOfficeStart {

	void start();

}

//实现1
public class Word implements IOfficeStart{

	@Override
	public void start() {
		System.out.println("Word...start...");
	}

}

//实现2
public class Excel implements IOfficeStart{

	@Override
	public void start() {
		System.out.println("Excel...start...");
	}

}

  

2.通过对象或类名获取类的信息

/**
 * 通过类对象来获取该类的所有方法、构造函数、变量
 */
public class ClassUtil {

        public static void main(String[] args) {

		Class c1 = int.class;
		Class c2 = void.class;
		System.out.println(c1.getName());
		System.out.println(c2.getName());

		ClassUtil.printClassMethods(new Double(1.0d));
		ClassUtil.printClassFields(new Integer(1));
		ClassUtil.printClassConstructors(new String());

	}

	/**
	 * 打印obj对象所在类的所有方法
	 * @param obj
	 */
	public static void printClassMethods(Object obj){
		//首先获取类的类类型
		Class c = obj.getClass();
		System.out.println(c.getName() + "类所有的方法:");

		//getMethods返回所有public方法,包括继承的方法
		//getDeclaredMethods()返回所有的方法,不包括继承的方法
		Method []ms = c.getMethods();

		//遍历集合打印每个方法,包括方法返回值,方法名,方法参数
		for (int i = 0; i < ms.length; i++) {
			Method m = ms[i];
			//返回类型
			System.out.print(m.getReturnType().getSimpleName() + " ");
			//方法名
			System.out.print(m.getName() + " (");
			//参数集合
			Class []args = m.getParameterTypes();
			for (Class class1 : args) {
				System.out.print(class1.getSimpleName() +",");
			}
			System.out.println(")");
		}

		System.out.println("\n\n");

	}

	/**
	 * 打印obj对象所在类的所有构造函数
	 */
	public static void printClassConstructors(Object obj){

		Class c = obj.getClass();
		System.out.println(c.getName() + "类的所有构造函数:");
		Constructor []cs = c.getDeclaredConstructors();
		for (int i = 0; i < cs.length; i++) {
			System.out.print(cs[i].getName() + " (");

			Class []paras = cs[i].getParameterTypes();
			for (Class class1 : paras) {
				System.out.print(class1.getName() + ",");

			}
			System.out.println(")");
		}
		System.out.println("\n\n");
	}

	/**
	 * 打印obj对象所在类的所有变量
	 */
	public static void printClassFields(Object obj){
		Class c = obj.getClass();
		System.out.println(c.getName() + "类的所有成员变量:");
		Field[] fields = c.getFields();
		for (int i = 0; i < fields.length; i++) {
			Field field = fields[i];
			System.out.println(field.getType().getName() + " " + field.getName());

		}
		System.out.println("\n\n");
	}
}

  

3.通过对象获取到所在类的某个方法后,通过反射的方式调用该方法

import java.lang.reflect.Method;

public class Main {
	public static void main(String[] args){
		A a = new A();
		//下面通过对象a来反射调用方法
		Class<? extends A> c = a.getClass();
		try {
			//Method m1 = c.getMethod("print1", new Class[]{String.class,String.class});
			Method m1 = c.getMethod("print1", String.class,String.class);
			//Method m2 = c.getMethod("print2",new Class[]{});
			Method m2 = c.getDeclaredMethod("print2");
			m1.invoke(a,"HELLO","world");
			m2.invoke(a);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

class A{
	public void print1(String a,String b){
		System.out.println(a.toLowerCase() +" "+ b.toUpperCase());
	}

	public void print2(){
		System.out.println("hello world");
	}
}

  

4.通过反射理解泛型(不能算是应用场景)

import java.lang.reflect.Method;
import java.util.ArrayList;

public class Main {
	public static void main(String[] args) {
		ArrayList list1 = new ArrayList();

		ArrayList<String> list2 = new ArrayList<String>();
		list2.add("hello");//ok
		//list2.add(1111);//false

		System.out.println(list1.getClass() == list2.getClass());//输出true

		//因为带泛型和不带泛型通过反射得到类类型都发现是==的
		//所以推测泛型的实质是在编译之前起到提醒的作用,在编译之后是没有泛型的
		//通过反射验证
		try {
			Method m = list1.getClass().getMethod("add", Object.class);
			m.invoke(list2, 1111);

			System.out.println(list2);//测试是否add进去1111
//			for (String string : list2) {
//				System.out.print(string);
//			}此时不能这么遍历
			for (Object obj : list2) {
				System.out.print(obj + " ");
			}//发现可以add
		} catch (Exception e) {
			// TODO: handle exception
		}

	}
}

  

时间: 2024-10-13 03:24:48

java中【反射(Reflect)】的常见应用场景的相关文章

java中反射学习整理

转载请注明:http://blog.csdn.net/j903829182/article/details/38405735 反射主要是指程序可以访问,检测和修改它本身的状态或行为的一种能力. java中反射是一种强大的工具,它能够创建灵活的代码,这些代码可以在运行时装载,无须在组件之间进行链接.反射允许在编写与执行时,使程序能够接入到jvm中的类的内部信息,而不是源代码中选定的类协作的代码.这使反射成为构建灵活应用代码的主要工具.需要注意的是,如果使用不当,反射的成本会很高. package

Java中反射的实现方式

所谓反射,是指在运行时状态中,获取类中的属性和方法,以及调用其中的方法的一种机制.这种机制的作用在于获取运行时才知道的类(Class)及其中的属性(Field).方法(Method)以及调用其中的方法,也可以设置其中的属性值. 在Java中实现反射最重要的一步,也是第一步就是获取Class对象,得到Class对象后可以通过该对象调用相应的方法来获取该类中的属性.方法以及调用该类中的方法. Java中反射有如下几种实现方式: 1.通过Class.forName()方法加载字符串,就可以得到该字符串

Java中反射机制(Reflection)研究及源码演示

如下内容内容是关于 Java中反射机制(Reflection)研究及演示的内容. package com.jiangqq.reflection; import java.lang.reflect.Method; public class Reflection1 { public static void main(String[] args) throws Exception { Class<?> tClass = Class.forName("java.lang.Class"

java中反射

反射 避免硬编码 类对象 (存储了类的信息的对象 类加载的产物) Class 类名.class 直接获得类对象 (简单类型的类对象 int.class) 类的对象.getClass() Class.forName("类名") 通过类名主动加载一个类并获得类对象 类对象.newInstance() 创建类的对象 java中反射,布布扣,bubuko.com

Java 中反射机制的深入研究

昨天学习了java的反射机制,今天继续深入学习一下. 一.通过反射操作数组 反射不光只能用在类中,也可用在任意的引用数据类型上.当然包括数组. 通过java.lang.reflect.Array 类 可操作数组,java.lang.reflect.Array 类 下面提供了很多方法. 例如 public static Object get(Object array,int index)throws IllegalArgumentException,ArrayIndexOutOfBoundsExc

Java中反射机制详解

序言 在学习java基础时,由于学的不扎实,讲的实用性不强,就觉得没用,很多重要的知识就那样一笔带过了,像这个马上要讲的反射机制一样,当时学的时候就忽略了,到后来学习的知识中,很多东西动不动就用反射,所以回过头来把这个给重新补一下,自己欠下的债,迟早是要还的. ---WH 一.什么是反射? 在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的

java中反射机制原理讲解

 反射,当时经常听他们说,自己也看过一些资料,也可能在设计模式中使用过,但是感觉对它没有一个较深入的了解,这次重新学习了一下,感觉还行吧! 一,先看一下反射的概念: 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 反射是Java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接.但是反射使用不当会成本很高! 看概念很晕的,继续往下看. 二,反射机制的

Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别(转)

一.Java的反射机制   每个Java程序执行前都必须经过编译.加载.连接.和初始化这几个阶段,后三个阶段如下图:  其中 i.加载是指将编译后的java类文件(也就是.class文件)中的二进制数据读入内存,并将其放在运行时数据区的方法区内,然后再堆区创建一个Java.lang.Class对象,用来封装类在方法区的数据结构.即加载后最终得到的是Class对象,并且更加值得注意的是:该Java.lang.Class对象是单实例的,无论这个类创建了多少个对象,他的Class对象时唯一的!!!!.

理解java中反射,区别Class.forName(),Class.forName().instance() ,new

先了解一下反射(这玩意着实让我理解了很久啊)博文参考(http://blog.csdn.net/cookieweb/article/details/7056277) 先了解一些基本的概念:运行时,编译时,编译型,解释型,类加载器,动态加载类  什么是编译?将原程序翻译成计算机语言,就是二进制代码,在java中是将.java文件也就是源程序翻译成.class的字节码  什么是编译时?将原程序翻译成计算机语言的过程中,将.java翻译为.class文件的过程  什么是运行时?就是在启动这个程序的时候

JAVA中反射机制六(java.lang.reflect包)

一.简介 java.lang.reflect包提供了用于获取类和对象的反射信息的类和接口.反射API允许对程序访问有关加载类的字段,方法和构造函数的信息进行编程访问.它允许在安全限制内使用反射的字段,方法和构造函数对其底层对等进行操作. 二.java.lang.reflect AccessibleObject类 java.lang.reflect.AccessibleObject类是Field,Method和Constructor类对象的基类. 它提供了将反射对象标记为在使用它时抑制默认Java