深入学习 Java的反射机制1

本文深入讲解Java反射机制的基础知识,包括Class类的使用方法、如何通过Class类获取对象的方法、成员变量及构造函数等信息,并提供了详细的代码示例。

深入学习 Java的反射机制1

本博文是学习了慕课网的案例:反射——Java高级开发必须懂的,觉得讲的很不错,整理并写点我的心得总结出来,希望和大家分享。废话不多说,我们从Class类的使用开始吧!


1 Class 类的使用

    理解:Java中万事万物皆是对象;
               类是也对象,类是java.lang.Class 类的实例对象;
              通过类类型,创建对象实例;   
 
       使用:

A    获取类类型的 三种表示方法:
  1. 类名.class方法---通过类建立
  2. 类的引用.getClass()方法----通过类实例建立
  3.  Class.forName("类名路径")方法---类建立
B    通过类类型创建实例对象
  • 如:类引用.newInstance();实例应用例如:类的动态加载技术
类的动态加载:

(1) 类的动态加载和静态加载: a   编译时---静态加载类     b    运行时---动态加载类

(2)如杀毒软件、QQ在线升级等都是使用类的动态加载技术实现的。 

(3)样例:Word 与 Excel 组件(类)等都是Office办法软件(Officeable接口)的实现:如使用动态加载类,在Word或Excel其中之一出现了问题之后,其他组件(类)都可以照样正常运行;同时,若要再增加一个PPT组件,可以只让PPT实现Officeable接口即可(这是接口的好处)。
(4)程序实现思路:定义接口(Officeable)--->动态加载类并生成实例对象(Class.forname(类全名")和newInstance())--->编写任意想要使用的类(实现接口Worl,Excel,PPT等)。
    程序如下所示:

//建立接口
package com.qyl.learn.reflect;

public interface Officeable {
	public void start();
}
//建立Excel组件
package com.qyl.learn.reflect;

public class Excel implements Officeable {

	@Override
	public void start() {
		System.out.println("start---Excel!");
	}
}
//客户端代码
package com.qyl.learn.reflect;

public class Client {

	public static void main(String[] args) {
		try {
			Class c = Class.forName("com.qyl.learn.reflect.Excel");
			//Class c = Class.forName(args[0]);  //模拟用户打开那个组件
			Officeable oa = (Officeable)c.newInstance();
			oa.start();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
//增加Word组件
<pre name="code" class="java">package com.qyl.learn.reflect;

public class Word implements Officeable {

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


 
C通过类类型获取对象的方法
  
/**
 * 
 * 要获取类的信息(method && Filed),首先要获取该类的类类型;
 * 获取类的类类型的方法有三种:
 * 1  类名.class;
 * 2  对象应用.getClass;
 * 3  Class.forname("类全名");
 *
 */
</pre><pre name="code" class="java">
<span style="white-space:pre">	</span>/**
	 *  打印方法信息
	 *  getMethods() -->public的方法,包含父类继承的
	 *  getDeclaredMethod()-->该类自己声明的方法,不问访问权限
	 *  getReturnType()-->返回值类型的类类型
	 *  getParameterType()-->参数列表类型的类类型
	 */
	public static void printMethodMessage(Object obj){
		
		//获取类的类类型
		Class c = obj.getClass();
		//获取类的名称
		System.out.println("该类的名称是"+c.getName());
		
		//获取类的方法
		/* 首先要得到Method类,数组Method[]中
		 * Method类   方法的实例对象  在java.lang.reflect.Method
		 * getMethods() -->public的方法,包含父类继承的
		 * getDeclaredMethod()-->该类自己声明的方法,不问访问权限
	 	 */
		Method[] methods = c.getMethods(); //得到public的方法,包含父类继承的
		
		for(int i = 0;i< methods.length;i++){
			
			//这里又得到了方法对象的返回值类类型
			Class returnType = methods[i].getReturnType(); //如 int.class
			//打印出方法返回值得类型名
			System.out.print(returnType.getName()+" ");
			//打印出方法名
			System.out.print(methods[i].getName()+ "(");
			
			//这里又得到了方法对象的参数的类类型  参数列表
			Class[] paramTypes = methods[i].getParameterTypes();
			//打印出各个参数的类型名
			for (Class class1 : paramTypes) {
				System.out.print(class1.getName()+",");
			}
			System.out.println(")");
		}
	}
</pre><pre name="code" class="java">//测试程序如下:
package com.qyl.learn.reflect;

public class ClassDome3 {
	public static void main(String[] args) {
		String s = "hello";
		ClassUtil.printMethodMessage(s);
		//ClassUtil.printFieldMessage(s);
		//ClassUtil.printConstructorsMessage(s);
		System.out.println("===========================================================");
		Integer int1 =1;
		ClassUtil.printMethodMessage(int1);
		//ClassUtil.printFieldMessage(int1);
		//ClassUtil.printConstructorsMessage(int1);
	}
}
打印结果如下:
该类的名称是java.lang.String
int hashCode()
int compareTo(java.lang.Object,)
int compareTo(java.lang.String,)
int indexOf(java.lang.String,int,)
int indexOf(java.lang.String,)
int indexOf(int,)
int indexOf(int,int,)
boolean equals(java.lang.Object,)
java.lang.String toString()
char charAt(int,)
int codePointAt(int,)
int codePointBefore(int,)
int codePointCount(int,int,)
int compareToIgnoreCase(java.lang.String,)
java.lang.String concat(java.lang.String,)
boolean contains(java.lang.CharSequence,)
boolean contentEquals(java.lang.StringBuffer,)
boolean contentEquals(java.lang.CharSequence,)
java.lang.String copyValueOf([C,int,int,)
java.lang.String copyValueOf([C,)
boolean endsWith(java.lang.String,)
boolean equalsIgnoreCase(java.lang.String,)
java.lang.String format(java.lang.String,[Ljava.lang.Object;,)
java.lang.String format(java.util.Locale,java.lang.String,[Ljava.lang.Object;,)
[B getBytes(java.nio.charset.Charset,)
[B getBytes()
[B getBytes(java.lang.String,)
void getBytes(int,int,[B,int,)
void getChars(int,int,[C,int,)
java.lang.String intern()
boolean isEmpty()
int lastIndexOf(java.lang.String,)
int lastIndexOf(int,)
int lastIndexOf(int,int,)
int lastIndexOf(java.lang.String,int,)
int length()
boolean matches(java.lang.String,)
int offsetByCodePoints(int,int,)
boolean regionMatches(int,java.lang.String,int,int,)
boolean regionMatches(boolean,int,java.lang.String,int,int,)
java.lang.String replace(char,char,)
java.lang.String replace(java.lang.CharSequence,java.lang.CharSequence,)
java.lang.String replaceAll(java.lang.String,java.lang.String,)
java.lang.String replaceFirst(java.lang.String,java.lang.String,)
[Ljava.lang.String; split(java.lang.String,int,)
[Ljava.lang.String; split(java.lang.String,)
boolean startsWith(java.lang.String,int,)
boolean startsWith(java.lang.String,)
java.lang.CharSequence subSequence(int,int,)
java.lang.String substring(int,)
java.lang.String substring(int,int,)
[C toCharArray()
java.lang.String toLowerCase()
java.lang.String toLowerCase(java.util.Locale,)
java.lang.String toUpperCase()
java.lang.String toUpperCase(java.util.Locale,)
java.lang.String trim()
java.lang.String valueOf([C,)
java.lang.String valueOf(int,)
java.lang.String valueOf(long,)
java.lang.String valueOf(float,)
java.lang.String valueOf(double,)
java.lang.String valueOf(java.lang.Object,)
java.lang.String valueOf(char,)
java.lang.String valueOf([C,int,int,)
java.lang.String valueOf(boolean,)
void wait()
void wait(long,int,)
void wait(long,)
java.lang.Class getClass()
void notify()
void notifyAll()
===========================================================
该类的名称是java.lang.Integer
int hashCode()
int reverseBytes(int,)
int compareTo(java.lang.Object,)
int compareTo(java.lang.Integer,)
boolean equals(java.lang.Object,)
java.lang.String toString(int,int,)
java.lang.String toString(int,)
java.lang.String toString()
java.lang.String toHexString(int,)
java.lang.Integer decode(java.lang.String,)
java.lang.Integer valueOf(java.lang.String,)
java.lang.Integer valueOf(java.lang.String,int,)
java.lang.Integer valueOf(int,)
int reverse(int,)
byte byteValue()
double doubleValue()
float floatValue()
int intValue()
long longValue()
short shortValue()
int parseInt(java.lang.String,)
int parseInt(java.lang.String,int,)
int bitCount(int,)
java.lang.Integer getInteger(java.lang.String,)
java.lang.Integer getInteger(java.lang.String,int,)
java.lang.Integer getInteger(java.lang.String,java.lang.Integer,)
int highestOneBit(int,)
int lowestOneBit(int,)
int numberOfLeadingZeros(int,)
int numberOfTrailingZeros(int,)
int rotateLeft(int,int,)
int rotateRight(int,int,)
int signum(int,)
java.lang.String toBinaryString(int,)
java.lang.String toOctalString(int,)
void wait()
void wait(long,int,)
void wait(long,)
java.lang.Class getClass()
void notify()
void notifyAll()




D     通过类类型获取对象的成员变量
<span style="white-space:pre">	</span>/**
	 * *******获取成员变量信息  * 获取构造函数信息**************
	 * 首先要得到Filed类,数组Field[]中
	 * Field类   成员变量的实例对象  java.lang.reflect.Field
	 * Field 中封装了许多成员变量的操作方法
	 * 如:getFields()-->得到所有public成员变量信息
	 *     getDeclaredField()-->得到自己声明的成员变量信息
	 */
	
	public static void printFieldMessage(Object obj) {
		
		//获取类的类类型
		Class c = obj.getClass();
		System.out.println("下面是成员变量的类型和名称:");
		
		//Field[] fields = c.getFields(); //得到所有public成员变量信息
		Field[] fields = c.getDeclaredFields();//得到自己声明的成员变量信息
		for (Field field : fields) {
			//得到成员变量的类型的类类型;
			Class fieldType = field.getType();
			//得到成员变量的类型名称
			String typeName = fieldType.getName();
			//得到成员变量的名称
			String fieldName = field.getName();
			//打印
			System.out.println(typeName+" "+fieldName);
		
		}
	}
//打印结果如下:
下面是成员变量的类型和名称:
[C value
int offset
int count
int hash
long serialVersionUID
[Ljava.io.ObjectStreamField; serialPersistentFields
java.util.Comparator CASE_INSENSITIVE_ORDER
===========================================================
下面是成员变量的类型和名称:
int MIN_VALUE
int MAX_VALUE
java.lang.Class TYPE
[C digits
[C DigitTens
[C DigitOnes
[I sizeTable
int value
int SIZE
long serialVersionUID

E通过类类型获取对象的构造函数
<span style="white-space:pre">	</span>/** 
	 *  *********获取构造函数信息**************************
	 *  Constructor 也是对象 ,其信息在java.lang.Constructor中封装
	 *	getConstructors()--->所有public 构造方法信息
	 *	getDeclaredConstructors()--->自己声明的构造方法信息
	 * 
	 */
	public static void printConstructorsMessage(Object obj){
		//获取类的类类型
		Class c = obj.getClass();
		System.out.println("下面是构造方法的信息:");
		//获取每个构造函数信息
	   //Constructor[] constructors = c.getConstructors();
		Constructor[] constructors = c.getDeclaredConstructors();
		for (Constructor constructor : constructors) {
			System.out.print(constructor.getName()+"(");
			//获取每个参数类型的类类型
			Class[] paramTypes = constructor.getParameterTypes();
			//打印出各个参数的类型名
			for (Class class1 : paramTypes) {
				System.out.print(class1.getName()+",");
			}
		System.out.println(")");	
		}
	}
//打印结果如下:
</pre><pre name="code" class="java">下面是构造方法的信息:
java.lang.String()
java.lang.String(java.lang.String,)
java.lang.String([C,)
java.lang.String([C,int,int,)
java.lang.String([I,int,int,)
java.lang.String([B,int,int,int,)
java.lang.String([B,int,)
java.lang.String(java.lang.StringBuilder,)
java.lang.String([B,int,int,java.lang.String,)
java.lang.String([B,int,int,java.nio.charset.Charset,)
java.lang.String([B,java.lang.String,)
java.lang.String([B,java.nio.charset.Charset,)
java.lang.String([B,int,int,)
java.lang.String([B,)
java.lang.String(java.lang.StringBuffer,)
java.lang.String(int,int,[C,)
===========================================================
下面是构造方法的信息:
java.lang.Integer(java.lang.String,)
java.lang.Integer(int,)


!!!!不好意思,今天整不完了,余下内容见:深入学习 Java的反射机制2!!!

2 方法的反射

3 成员变量的反射

4 构造函数的反射

5 Java的类加载机制




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值