直接上代码了
例子1:
@Request(value="dtl", parameter = "123") //自定义注解的使用
public class DtlTest {
String name;
int age;
String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
System.out.println("age is: "+age);
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String toString(){
String str = "this is toString method";
return str;
}
public static void main(String[] args) {
Class<?> t1 = null;
Class<?> t2 = null;
Class<?> t3 = null;
try {
//以下都可以
t1 = Class.forName("DtlTest");//完整包名
t2 = new DtlTest().getClass();
t3 = DtlTest.class;
DtlTest t4 = new DtlTest();
Method[] method = t3.getDeclaredMethods();//获取所有方法
Method method1 = t3.getMethod("toString");//获取指定方法
//invoke方法参数,第一个就是你要调用的方法所在的类实例,第二个是入参Object数组
System.out.println("method1:"+method1.invoke(DtlTest.class.newInstance()));
System.out.println("method1:"+method1.invoke(t4));//这里可以直接使用类的实例
for (int i = 0; i < method.length; i++) {
if("toString".equals(method[i].getName())){
String str = (String) method[i].invoke(DtlTest.class.newInstance());
System.out.println(str);
}
if("setAge".equals(method[i].getName())){
method[i].invoke(DtlTest.class.newInstance(),new Object[]{33});
}
}
//解析注解,获取注解成员值
if(t3.isAnnotationPresent(Request.class)){//判断类上是否有指定注解
Request request = t3.getAnnotation(Request.class);
//至此可以获取注解的成员等一切信息了
System.out.println("request.value()=="+request.value());
System.out.println("request.parameter()=="+request.parameter());
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//以下是自定义的注解
/**
如果注解只有一个成员,则成员名必须取名为value(),在使用时可以忽略成员名和赋值号(=),
如@Description("使用注解的实例")。注解类拥有多个成员时,
如果仅对value成员进行赋值则也可不使用赋值号,如果同时对多个成员进行赋值,则必须使用赋值号,
如@DeclareParents (value = "NaiveWaiter", defaultImpl = SmartSeller.class)。
*/
/**
ANNOTATION_TYPE
注释类型声明
CONSTRUCTOR
构造方法声明
FIELD
字段声明(包括枚举常量)
LOCAL_VARIABLE
局部变量声明
METHOD
方法声明
PACKAGE
包声明
PARAMETER
参数声明
TYPE
类、接口(包括注释类型)或枚举声明
*/
/**
枚举常量摘要
CLASS
编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。
RUNTIME
编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。
SOURCE
编译器要丢弃的注释。
*/
//指定注解的类型、保留范围
@Target(ElementType.TYPE) //指定注释用在什么地方
@Retention(RetentionPolicy.RUNTIME) //指定注释保留级别,只有此级别才可以使用反射获取
public @interface Request {
String value() default "CLASS_NAME";//可以使用default设置默认值
String parameter();
}
例子2
//通过反射实现bean的属性值的拷贝
private static void copyProperties(Object obj, Object dest, Class soureClass, Class destClass) {
Method[] sourceMethods = soureClass.getMethods();
Method[] destMethods = destClass.getMethods();
for (Method getMethod : sourceMethods) {
try {
if (getMethod.getName().startsWith(GET)) {//拿到get方法
for (Method setMethod : destMethods) {
// 方法名及参数类型类型都一致才复制值
if (setMethod.getName().startsWith(SET)
&& getMethod.getName().replaceFirst(GET, EMPTY)
.equals(setMethod.getName().replaceFirst(SET, EMPTY))
&& getMethod.getReturnType().equals(setMethod.getParameterTypes()[0])) {
setMethod.setAccessible(true);//值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。也就是访问权限修饰符private等失去作用。
getMethod.setAccessible(true);
//反射调用目标类的set方法,参数是源通过get方法获取的值
setMethod.invoke(dest, getMethod.invoke(obj));
}
}
}
} catch (Exception e) {
logger.error(e.toString());
continue;
}
}
}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。