Java 反射详解

反射是java中的一个工具集合,主要用于JavaBeans中,它在分析类能力时功能非常强大

反射主要功能
在运行中分析类的能力
在运行中查看对象,例如,编写一个toString方法供所有类使用
实现通用的数组操作代码
利用Method对象,这个对象很想C++中的指针


java核心卷

************************************************************************************

在程序运行期间,java运行时程序始终为所有的对象维护一个被称为运行时的类型标识,这个信息跟踪这每一个对象所属的类,虚拟机利用运行时类型信息选择相应的方法执行。然而可以通过专门的java类访问这些信息,保存这些信息的类被称为Class

************************************************************************************



具体使用如下

Date d=new Date();Class c1=d.getClass();
String name=c1.getName();


 

输出结果是java.util.Date,因为包名也会作为类名的一部分

也可以通过类名生成Class对象,但是要捕捉异常

try{
String name="java.util.Date";
Class c1=class.forName(className);
}catch (ClassNotFoundException e)
 {// TODO: handle exception
e.printStackTrace();
}



也可以在java类型后面直接加.class类型来直接获取Java类型

Class example=Date.class

两个Class类之间可以通过==来比较如

a.getClass()==b.getClass();

在反射中newInstance()也是一个非常重要的方法,用于根据Class类型创造一个该Class的实例

具体使用如下

sample.getClass.newInstance();
//或者,下面这种要捕捉异常
Object o=Class.forName("java.util.Date").newInstance();


在java.lang.reflect包中有三个类 

java.lang.reflect中的三个类
Field 描述域
Method 描述方法
Constructor 描述构造器


三个类都有getName方法,Filed类还有一个getType方法,具体使用如下

输入完整路径比如我的 输入jyh.A

package jyh;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Scanner;

public class test1 {
	public static void main(String[] args) {
	String name;
	System.out.println("请输入完整类名");
	Scanner in=new Scanner(System.in);
	name=in.next();
	try
	{
		//getDeclaredFields等得到域 方法和构造器的方法会在后面介绍
		Class sample=Class.forName(name);
		Field[] aField=sample.getDeclaredFields();
		System.out.println(aField[0].getName()+" "+aField[0].getType());
		System.out.println(aField[1].getName()+" "+aField[1].getType());
		
		Method[] aMethod=sample.getDeclaredMethods();
		System.out.println(aMethod[0].getName());
		System.out.println(aMethod[1].getName());
		
		Constructor[] aConstructor=sample.getDeclaredConstructors();
		System.out.println(aConstructor[0].getName());
		System.out.println(aConstructor[1].getName());
	}
	catch (ClassNotFoundException e) {
		// TODO: handle exception
		e.printStackTrace();
	}
	}
}

class A
{
	private int a=1;
	public double b=2;
	private int return1()
	{
		return 1;
	}
	public int return2()
	{
		return 2;
	}
	private A(int a,int b)
	{
		
	}
	public A()
	{
		
	}
}

然后得到的输出时
a int
b double
return2
return1
jyh.A
jyh.A


除了上面的方法我们还可以使用getModifiers具体实现如下,它是通过不同的开关位置来区分public static这些修饰符

和上面一样输入jyh.B后

package jyh;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Scanner;

public class test2 {
	public static void main(String[] args) {
		String name;
		System.out.println("请输入完整类名");
		Scanner in=new Scanner(System.in);
		name=in.next();
		try
		{
			//getDeclaredFields等得到域 方法和构造器的方法会在后面介绍
			Class sample=Class.forName(name);
			Field[] fields=sample.getDeclaredFields();
			Method[] methods=sample.getDeclaredMethods();
			Constructor[] constructors=sample.getDeclaredConstructors();
			System.out.println(fields[0].getModifiers());
			System.out.println(fields[1].getModifiers());
			System.out.println(fields[2].getModifiers());
			System.out.println(fields[3].getModifiers());
			System.out.println(fields[4].getModifiers());
			System.out.println(fields[5].getModifiers());
			System.out.println(fields[6].getModifiers());
			System.out.println(fields[7].getModifiers());
			
			System.out.println(methods[0].getModifiers());
			System.out.println(methods[1].getModifiers());
			System.out.println(constructors[0].getModifiers());
		    System.out.println(constructors[1].getModifiers());
		}
		catch (ClassNotFoundException e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
}

class B
{
	public int a=1;
	private double b=2;
	static public int c=3;
	static private int d=4;
	final public int e=5;
	final private int f=6;
	static final public int g=7;
	static final private int h=8;
	//*********
			
	public int return2()
	{
		return 2;
	}
	private int return1()
	{
		return 1;
	}
	public B()
	{
		
	}
	private B(int a,int b)
	{
		
	}
}

最后的输出结果
1
2
9
10
17
18
25
26
2
1
2
1

getModifiers的具体对应数值如下

它是通过二进制来表示的,如果有多个返回和,比如public static返回9

getModifiers
public1
private2
protected4
static8
final16
synchronized32
volatile64
transient128
native256
interface512
abstract1024
strict2048

下面这些方法通过检测对应的修饰符位来确定该域 方法或者构造器是否有该修饰符

函数如下

java.lang.reflect.Modifier
static boolean isAbstract(int modifiers)
static boolean isFinal(int modifers)
static boolean isInterface(int modifiers)
static boolean isNative(int modifiers)
static boolean isPrivate(int modifiers)
static boolean isProtected(int modifiers)
static boolean isPublic(int modifiers)
static boolean isStatic(int modifiers)
static boolean isStrict(int modifiers)
static boolean isSynchronized(int modifiers)
static boolean isVolatile(int modifiers)

具体使用在下面那格例子中有


上面提到的那些getMethods等方法到底怎么用呢?

其实这些方法都是Class类的总共有6个

getFields,getMethods,getConstructors,getDeclaredFields,getDeclaredMethods,getDeclaredConstructors

他们有的区别主要是方法名中包含Declared的返回的是全部的域,方法,构造器,而没有Declared返回的则只是public类型的

另外没有Declared的方法也返回包括从超类继承来的公有方法,但是有Declared的则不会返回从超类继承来的方法。


具体实例如下,可以输入java.util.Date

package jyh;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Date;
import java.util.Scanner;

public class test {
	public static void main(String[] args) {
		System.out.println("请输入一个类:");
		Scanner in=new Scanner(System.in);
		String name=in.next();
		try{
			Class c1=Class.forName(name);
			System.out.println("getDeclaredConstructors所有的构造器:");
			Constructor[] constructors=c1.getDeclaredConstructors();
			for(Constructor c:constructors)
			{
				System.out.println(c.toString());
			}
			
			System.out.println("getDeclaredConstructors公有的构造器:");
			for(Constructor c:constructors)
			{
				if(Modifier.isPublic(c.getModifiers()))
					System.out.println(c.toString());
			}
			System.out.println("getDeclaredConstructores私有的构造器:");
			{
				if(Modifier.isPrivate(c1.getModifiers()))
					System.out.println(c1.toString());
			}
			
			System.out.println("getConstructors所有的构造器:");
			Constructor[] Notconstructors=c1.getConstructors();
			for(Constructor c:Notconstructors)
			{
				System.out.println(c.toString());
			}
			
			System.out.println("getDeclaredFields所有的域");
			Field[] fields=c1.getDeclaredFields();
			for(Field f:fields)
			{
				System.out.println(f.toString());
			}
			
			System.out.println("getDeclaredFields所有的公有域");
			for(Field f:fields)
			{
				if(Modifier.isPublic(f.getModifiers()))
					System.out.println(f.toString());
			}
			
			System.out.println("getDeclaredFields所有的私有域");
			for(Field f:fields)
			{
				if(Modifier.isPrivate(f.getModifiers()))
					System.out.println(f.toString());
			}
			
			System.out.println("getFields所有的域");
			Field[] Notfields=c1.getFields();
			for(Field f:Notfields)
			{
				System.out.println(f.toString());
			}
			
			System.out.println("getDeclaredMethods所有的方法");
			Method[] methods=c1.getDeclaredMethods();
			for(Method m:methods)
			{
				System.out.println(m.toString());
			}
			
			System.out.println("getDeclaredMethods所有的公有方法");
			for(Method m:methods)
			{
				if(Modifier.isPublic(m.getModifiers()))
					System.out.println(m.toString());
			}
			
			System.out.println("getDeclaredMethods所有的私有方法");
			for(Method m:methods)
			{
				if(Modifier.isPrivate(m.getModifiers()))
					System.out.println(m.toString());
			}
			
			System.out.println("getMethods所有的方法");
			Method[] Notmethods=c1.getMethods();
			for(Method m:Notmethods)
			{
				System.out.println(m.toString());
			}	
			
		}catch (ClassNotFoundException e) {
			// TODO: handle exception
			e.printStackTrace();
			int[] x=new int[Integer.MAX_VALUE];
		}

	}
}
输出结果是

getDeclaredConstructors所有的构造器:
public java.util.Date(int,int,int,int,int,int)
public java.util.Date(java.lang.String)
public java.util.Date()
public java.util.Date(long)
public java.util.Date(int,int,int)
public java.util.Date(int,int,int,int,int)
getDeclaredConstructors公有的构造器:
public java.util.Date(int,int,int,int,int,int)
public java.util.Date(java.lang.String)
public java.util.Date()
public java.util.Date(long)
public java.util.Date(int,int,int)
public java.util.Date(int,int,int,int,int)
getDeclaredConstructores私有的构造器:
getConstructors所有的构造器:
public java.util.Date(int,int,int,int,int,int)
public java.util.Date(java.lang.String)
public java.util.Date()
public java.util.Date(long)
public java.util.Date(int,int,int)
public java.util.Date(int,int,int,int,int)
getDeclaredFields所有的域
private static final sun.util.calendar.BaseCalendar java.util.Date.gcal
private static sun.util.calendar.BaseCalendar java.util.Date.jcal
private transient long java.util.Date.fastTime
private transient sun.util.calendar.BaseCalendar$Date java.util.Date.cdate
private static int java.util.Date.defaultCenturyStart
private static final long java.util.Date.serialVersionUID
private static final java.lang.String[] java.util.Date.wtb
private static final int[] java.util.Date.ttb
getDeclaredFields所有的公有域
getDeclaredFields所有的私有域
private static final sun.util.calendar.BaseCalendar java.util.Date.gcal
private static sun.util.calendar.BaseCalendar java.util.Date.jcal
private transient long java.util.Date.fastTime
private transient sun.util.calendar.BaseCalendar$Date java.util.Date.cdate
private static int java.util.Date.defaultCenturyStart
private static final long java.util.Date.serialVersionUID
private static final java.lang.String[] java.util.Date.wtb
private static final int[] java.util.Date.ttb
getFields所有的域
getDeclaredMethods所有的方法
public boolean java.util.Date.after(java.util.Date)
public boolean java.util.Date.before(java.util.Date)
public boolean java.util.Date.equals(java.lang.Object)
public java.lang.String java.util.Date.toString()
public int java.util.Date.hashCode()
public java.lang.Object java.util.Date.clone()
public int java.util.Date.compareTo(java.util.Date)
public int java.util.Date.compareTo(java.lang.Object)
private void java.util.Date.readObject(java.io.ObjectInputStream) throws java.io.IOException,java.lang.ClassNotFoundException
private void java.util.Date.writeObject(java.io.ObjectOutputStream) throws java.io.IOException
private final sun.util.calendar.BaseCalendar$Date java.util.Date.normalize(sun.util.calendar.BaseCalendar$Date)
private final sun.util.calendar.BaseCalendar$Date java.util.Date.normalize()
public static long java.util.Date.parse(java.lang.String)
public int java.util.Date.getDate()
public static java.util.Date java.util.Date.from(java.time.Instant)
public long java.util.Date.getTime()
private static final java.lang.StringBuilder java.util.Date.convertToAbbr(java.lang.StringBuilder,java.lang.String)
private final sun.util.calendar.BaseCalendar$Date java.util.Date.getCalendarDate()
private static final sun.util.calendar.BaseCalendar java.util.Date.getCalendarSystem(int)
private static final sun.util.calendar.BaseCalendar java.util.Date.getCalendarSystem(sun.util.calendar.BaseCalendar$Date)
private static final sun.util.calendar.BaseCalendar java.util.Date.getCalendarSystem(long)
public int java.util.Date.getDay()
public int java.util.Date.getHours()
private static final synchronized sun.util.calendar.BaseCalendar java.util.Date.getJulianCalendar()
static final long java.util.Date.getMillisOf(java.util.Date)
public int java.util.Date.getMinutes()
public int java.util.Date.getMonth()
public int java.util.Date.getSeconds()
private final long java.util.Date.getTimeImpl()
public int java.util.Date.getTimezoneOffset()
public int java.util.Date.getYear()
public void java.util.Date.setDate(int)
public void java.util.Date.setHours(int)
public void java.util.Date.setMinutes(int)
public void java.util.Date.setMonth(int)
public void java.util.Date.setSeconds(int)
public void java.util.Date.setYear(int)
public java.lang.String java.util.Date.toGMTString()
public java.time.Instant java.util.Date.toInstant()
public java.lang.String java.util.Date.toLocaleString()
public void java.util.Date.setTime(long)
public static long java.util.Date.UTC(int,int,int,int,int,int)
getDeclaredMethods所有的公有方法
public boolean java.util.Date.after(java.util.Date)
public boolean java.util.Date.before(java.util.Date)
public boolean java.util.Date.equals(java.lang.Object)
public java.lang.String java.util.Date.toString()
public int java.util.Date.hashCode()
public java.lang.Object java.util.Date.clone()
public int java.util.Date.compareTo(java.util.Date)
public int java.util.Date.compareTo(java.lang.Object)
public static long java.util.Date.parse(java.lang.String)
public int java.util.Date.getDate()
public static java.util.Date java.util.Date.from(java.time.Instant)
public long java.util.Date.getTime()
public int java.util.Date.getDay()
public int java.util.Date.getHours()
public int java.util.Date.getMinutes()
public int java.util.Date.getMonth()
public int java.util.Date.getSeconds()
public int java.util.Date.getTimezoneOffset()
public int java.util.Date.getYear()
public void java.util.Date.setDate(int)
public void java.util.Date.setHours(int)
public void java.util.Date.setMinutes(int)
public void java.util.Date.setMonth(int)
public void java.util.Date.setSeconds(int)
public void java.util.Date.setYear(int)
public java.lang.String java.util.Date.toGMTString()
public java.time.Instant java.util.Date.toInstant()
public java.lang.String java.util.Date.toLocaleString()
public void java.util.Date.setTime(long)
public static long java.util.Date.UTC(int,int,int,int,int,int)
getDeclaredMethods所有的私有方法
private void java.util.Date.readObject(java.io.ObjectInputStream) throws java.io.IOException,java.lang.ClassNotFoundException
private void java.util.Date.writeObject(java.io.ObjectOutputStream) throws java.io.IOException
private final sun.util.calendar.BaseCalendar$Date java.util.Date.normalize(sun.util.calendar.BaseCalendar$Date)
private final sun.util.calendar.BaseCalendar$Date java.util.Date.normalize()
private static final java.lang.StringBuilder java.util.Date.convertToAbbr(java.lang.StringBuilder,java.lang.String)
private final sun.util.calendar.BaseCalendar$Date java.util.Date.getCalendarDate()
private static final sun.util.calendar.BaseCalendar java.util.Date.getCalendarSystem(int)
private static final sun.util.calendar.BaseCalendar java.util.Date.getCalendarSystem(sun.util.calendar.BaseCalendar$Date)
private static final sun.util.calendar.BaseCalendar java.util.Date.getCalendarSystem(long)
private static final synchronized sun.util.calendar.BaseCalendar java.util.Date.getJulianCalendar()
private final long java.util.Date.getTimeImpl()
getMethods所有的方法
public boolean java.util.Date.after(java.util.Date)
public boolean java.util.Date.before(java.util.Date)
public boolean java.util.Date.equals(java.lang.Object)
public java.lang.String java.util.Date.toString()
public int java.util.Date.hashCode()
public java.lang.Object java.util.Date.clone()
public int java.util.Date.compareTo(java.util.Date)
public int java.util.Date.compareTo(java.lang.Object)
public static long java.util.Date.parse(java.lang.String)
public int java.util.Date.getDate()
public static java.util.Date java.util.Date.from(java.time.Instant)
public long java.util.Date.getTime()
public int java.util.Date.getDay()
public int java.util.Date.getHours()
public int java.util.Date.getMinutes()
public int java.util.Date.getMonth()
public int java.util.Date.getSeconds()
public int java.util.Date.getTimezoneOffset()
public int java.util.Date.getYear()
public void java.util.Date.setDate(int)
public void java.util.Date.setHours(int)
public void java.util.Date.setMinutes(int)
public void java.util.Date.setMonth(int)
public void java.util.Date.setSeconds(int)
public void java.util.Date.setYear(int)
public java.lang.String java.util.Date.toGMTString()
public java.time.Instant java.util.Date.toInstant()
public java.lang.String java.util.Date.toLocaleString()
public void java.util.Date.setTime(long)
public static long java.util.Date.UTC(int,int,int,int,int,int)
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()


在java核心卷中展示了一种打印一个类全部信息的方法代码

如下

package jyh;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;

public class ReflectionTest {
	public static void main(String[] args) {
		String name;
		if(args.length>0)name=args[0];
		else
		{
			Scanner in=new Scanner(System.in);
			System.out.println("Enter class name (e.g.java.util.Date):");
			name=in.next();
		}
		try{
			Class c1=Class.forName(name);
			Class superc1=c1.getSuperclass();
			String modifiers=Modifier.toString(c1.getModifiers());
			if(modifiers.length()>0)System.out.println(modifiers+" ");
			System.out.println("class "+name);
			if(superc1!=null&&superc1!=Object.class)System.out.println(" extends "+superc1.getName());
			System.out.println("\n{\n");
			printConstructors(c1);
			System.out.println();
			printMethods(c1);
			System.out.println();
			printFields(c1);
			System.out.println("}");
			
		}
		catch(ClassNotFoundException e)
		{
			e.printStackTrace();
		}
		System.exit(0);
	}
	
	public static void printConstructors(Class c1)
	{
		Constructor[] constructors=c1.getDeclaredConstructors();
		for(Constructor c:constructors)
		{
			String name=c.getName();
			System.out.println("  ");
			String modifiers=Modifier.toString(c.getModifiers());
			if(modifiers.length()>0)System.out.println(modifiers+" ");
			System.out.print(name+"(");
			
			Class[] paramTypes=c.getParameterTypes();
			for(int j=0;j<paramTypes.length;j++)
			{
				if(j>0)
					System.out.print(", ");
				System.out.print(paramTypes[j].getName());
			}
			System.out.println(");");
		}
	}
	
	public static void printMethods(Class c1)
	{
		Method[] methods=c1.getDeclaredMethods();
		for(Method m:methods)
		{
			Class retType=m.getReturnType();
			String name=m.getName();
			
			System.out.print("   ");
			String modifiers=Modifier.toString(m.getModifiers());
			if(modifiers.length()>0)System.out.print(modifiers+" ");
			System.out.print(retType.getName()+" "+name+",");
			Class[] paramTypes=m.getParameterTypes();
			for(int j=0;j<paramTypes.length;j++)
			{
				if(j>0)System.out.println(", ");
				System.out.println(paramTypes[j].getName());
			}
			System.out.println("),");
		}
	}
	
	public static void printFields(Class c1)
	{
		Field[] fields=c1.getDeclaredFields();
		
		for(Field f:fields)
		{
			Class type=f.getType();
			String name=f.getName();
			System.out.print("   ");
			String modifiers=Modifier.toString(f.getModifiers());
			if(modifiers.length()>0)System.out.print(modifiers+" ");
			System.out.println(type.getName()+" "+name+";");
		}
	}
}




                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值