java提供了对运行时class文件信息获取功能的支持,对编写通用组件和底层框架有着重大意义。
Jdk提供此功能的支持类:java.lang.Class
知识提醒:
1、每个Class对象代表了一个class文件信息。所以一个类加载器里只会有一个Class对象。
2、Class对象本身也是Object对象。
3、这个类算是java提供反射功能的一部分,虽然没有在java.lang.reflect包里。
下面这个例子,算是对此类各个方法功能的一个探索和测试,希望对大家有用~
package com.horizon.reflect;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER,ElementType.TYPE,ElementType.CONSTRUCTOR })
@interface Note {
public boolean require() default true;
public String note() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER,ElementType.TYPE,ElementType.CONSTRUCTOR })
@interface Type {
public boolean require() default true;
public String type() default "";
}
@Inherited //标记这个注解是否可以被其注解的接口的子类获取
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER,ElementType.TYPE,ElementType.CONSTRUCTOR })
@interface Face {
public boolean require() default true;
public String face() default "";
}
interface IModel<T>{
@Face(face="method->face")
public boolean loginUser(String username,String password) throws RuntimeException,SQLException;
}
@Face
abstract class AbastractUser{
public String rowid;
protected Integer Id;
}
@Note(note= "calss->B",require = false)
public class LoginModel<T> extends AbastractUser implements IModel<T>{
/**
*
*/
private static final long serialVersionUID = -2537216038308998595L;
@Note(note="field->note")
@Type(type="field->type")
public List<String> note = Arrays.asList("defaultValue");
private String username;
private String password;
public LoginModel(){
}
public LoginModel(String username,String password,Integer id){
}
@Note(note="CONSTRUCTOR->B")
public LoginModel(@Note(note = "p->note") @Type(type = "p->type") String username,String password){
this.username = username;
this.password = password;
}
@Note(note = "method ->login()",require = true)
public void login(@Note(note = "p->username") String username, @Note(note = "p->password")String password) {
}
@Note(note = "method ->login()",require = true)
@Type(type = "p->type->username",require = false)
public boolean loginUser(@Note(note = "p->note->username") @Type(type = "p->type->username") String username, @Type(type = "p->password")String password)
throws RuntimeException,SQLException{
return true;
}
public <N,P> N getUserInfo(){
return null;
}
public List<String> getNote() {
return note;
}
public void setNote(List<String> note) {
this.note = note;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
package com.horizon.reflect;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import org.junit.Test;
/**
* @author create by [[email protected]]新春.王[/url] <br>
* date :Apr 20, 2013 10:34:04 AM
*
* Class反射功能测试
* 1、继承关系相关的信息和转化功能
* 2、成员、方法、构造方法 相关的功能
* 3、Class 基本属性相关的功能。eg:类型(接口,数组,枚举)
* 4、资源相关的功能
* 5、注解相关的功能
* 6、类加载相关的功能
*/
public class ClassReflect {
private Class<?> targetClass = LoginModel.class;
public static void main(String[] args) {
}
/**
* 与资源相关,从当前class的相对路径或者绝对路径找
targetClass.getResourceAsStream(name)
*/
@Test
public void testgetResource(){
//URL url = targetClass.getResource("..\\nio\\src.txt");
URL url = targetClass.getResource("");
System.out.println(url);
try {
InputStream input = url.openStream();
BufferedInputStream bis = new BufferedInputStream(input);
byte[] b = new byte[1024];
while(bis.read(b) != -1){
System.out.println(new String(b));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
}
}
/**
* 强制转化类型
*/
@Test
public void testCast(){
Class<?> superClass = targetClass.getSuperclass();
LoginModel model = new LoginModel();
AbastractUser obj = (AbastractUser)superClass.cast(model);
System.out.println(obj == model);
}
/**
* 获取父类
*/
@Test
public void testgetSuperclass(){
Class<?> superClass = targetClass.getSuperclass();
System.out.println(superClass);
System.out.println(superClass.getSuperclass());
}
/**
* 测试 实例 和实例Class之间的关系 功能类似于 instanceof operator
*/
@Test
public void testIsInstance(){
LoginModel model = new LoginModel();
System.out.println(targetClass.isInstance(model)); //true
System.out.println(IModel.class.isInstance(model));//true
System.out.println(model instanceof IModel);
System.out.println((Integer)1 instanceof Integer);
}
/**
* 测试一个接口是否是接口、数组、枚举、注解、基本类型、
*/
@Test
public void testIsType() {
System.out.println(targetClass.isInterface()); //false
Class<Serializable> cs = Serializable.class;
System.out.println("cs.isInterface():"+cs.isInterface()); //true
Class<?> abstractClass = AbastractUser.class;
System.out.println("Type.class.isAnnotation():"+Type.class.isAnnotation());
System.out.println("Integer.class.isPrimitive():"+Integer.class.isPrimitive());
System.out.println("int.class.isPrimitive():"+int.class.isPrimitive());
int[] intArr = new int[100];
System.out.println("intArr.getClass().isArray():"+intArr.getClass().isArray());
System.out.println("Integer.TYPE.isPrimitive():"+Integer.TYPE.isPrimitive());
System.out.println("int.class == Integer.TYPE:"+(int.class == Integer.TYPE));
}
/**
* LoginModel.class 生成实例 note:
* 必须保证有默认构造函数(如果调用方法:newInstance)或者通过Constructor来生成实例
*
* @throws InstantiationException
* @throws IllegalAccessException
*/
@Test
public void testNewInstance() throws InstantiationException,
IllegalAccessException {
Class<LoginModel> loginModel = LoginModel.class;
LoginModel model = loginModel.newInstance();
model.setNote(new ArrayList<String>());
model.setUsername("xinchun.wang");
System.out.println(model.getUsername());
}
/**
* 测试获取LoginModel实现的所有接口
*/
@Test
public void testGetInterfaces() {
Class<?> bClass = LoginModel.class;
Class[] interfaces = bClass.getInterfaces();
System.out.println(Arrays.toString(interfaces));
java.lang.reflect.Type[] genericType = bClass.getGenericInterfaces();
System.out.println(Arrays.toString(genericType));
for (java.lang.reflect.Type item : genericType) {
if (item instanceof ParameterizedType) {
ParameterizedType type = (ParameterizedType) item;
// 获取原始类型
System.out.println(type.getRawType());
// 获取真实的参数类型
System.out.println(Arrays.toString(type.getActualTypeArguments()));
// 意义不大
System.out.println(type.getOwnerType());
}
}
}
/**
* 获取LoginModel.class 构造函数
*
* @throws Exception
* @throws SecurityException
*/
@Test
public void testGetConstructors() throws SecurityException, Exception {
Class<?> bClass = LoginModel.class;
// 获取所有构造函数的注解
Constructor[] cons = bClass.getConstructors();
System.out.println(Arrays.toString(cons));
// 获取特定的构造函数, note:获取不到将抛出异常
Constructor con = bClass.getConstructor(String.class, Integer.class);
System.out.println(con);
}
/**
* 获取LoginModel.class 类级别的注解
*/
@Test
public void testGetAnnotations() {
Class<?> bClass = LoginModel.class;
// 获取LoginModel.class的所有注解。包括可继承的注解。
Annotation[] arrAnno = bClass.getAnnotations();
System.out.println(Arrays.toString(arrAnno));
// 获取LoginModel.class特定的注解
Note note = bClass.getAnnotation(Note.class);
System.out.println(note);
// 获取在LoginModel.class 上直接声明的注解
Annotation[] dAnnoArr = bClass.getDeclaredAnnotations();
System.out.println(Arrays.toString(dAnnoArr));
}
/**
* 获取数组类型的Class,根据getComponentType 获取数组中的元素类型
*/
@Test
public void testArrayGetComponentType() {
int[] intArr = new int[100];
Class<?> arrClass = intArr.getClass().getComponentType();
System.out.println(arrClass);
Integer[] integerArr = new Integer[100];
Class<?> integerArrClass = integerArr.getClass().getComponentType();
System.out.println(integerArrClass);
}
/**
* 测试Class的基本功能
*/
@Test
public void testClassBasic() {
Class<?> bClass = LoginModel.class;
// 简单名字
String simpleName = bClass.getSimpleName();
System.out.println(simpleName);
// 包含包的类名字
System.out.println(bClass.getName());
System.out.println(bClass.getCanonicalName());
System.out.println(bClass.getClass());
System.out.println(Arrays.toString(bClass.getClasses()));
System.out.println(Arrays.toString(bClass.getDeclaredClasses()));
}
/**
* 获取LoginModel.class 所有可以访问的成员 note:公共访问、包括父类
*
* @throws Exception
* @throws SecurityException
*/
@Test
public void testGetFields() throws SecurityException, Exception {
Class<?> bClass = LoginModel.class;
Field[] fields = bClass.getFields();
System.out.println(Arrays.toString(fields));
// 可以访问父类的成员
Field field = bClass.getField("rowid");
System.out.println(field);
}
/**
* 获取LoginModel.class 所有的成员(继承的不返回) note: 无论field 是否是私有都可以获取
*/
@Test
public void testGetDeclaredFields() {
Class<?> bClass = LoginModel.class;
Field[] fArr = bClass.getDeclaredFields();
for (Field field : fArr) {
System.out.println("field_name: " + field.getName());
}
}
}