反射
为什么要使用反射?
1,增加程序的灵活性,可扩展性,动态创建对象。
2,框架必备,任何框架的封装都要用反射。(框架的灵魂)
获取Class对象的三种方式?
1,Class.forName();
2,类名.class;
3,对象.getClass();
使用类反射创建对象:.newInstance();
获取全部的属性信息:.getDeclaredFields();
获取公共的属性信息:getFields()
获取单个属性:getFields()
暴力反射.setAccessible(true);
获取方法:invoke()
注解
元注解 默认的注解,自定义必须要加上
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target { ElementType[] value(); } @Target(ElementType.TYPE) //接口、类、枚举、注解 @Target(ElementType.FIELD) //字段、枚举的常量 @Target(ElementType.METHOD) //方法 @Target(ElementType.PARAMETER) //方法参数 @Target(ElementType.CONSTRUCTOR) //构造函数 @Target(ElementType.LOCAL_VARIABLE)//局部变量 @Target(ElementType.ANNOTATION_TYPE)//注解 @Target(ElementType.PACKAGE) ///包
基于自定义注解和反射的增加小案例
public static String insert(Object obj) throws Exception{
StringBuffer sb=new StringBuffer("insert into ");
Class<?> aClass = obj.getClass();//通过穿过来的属性获取class
//根据传过来的注解的名字获取当前类里面的注解
MyTable annotation = aClass.getAnnotation(MyTable.class);//如果没有加注解则为null
//拼接数据库名
if (annotation==null){//如果为null时,则拼接类名
sb.append(aClass.getName().substring(aClass.getName().lastIndexOf(".")+1));
}else {//如果有值时,则拼接注解内的名字
sb.append(annotation.name());
}
sb.append("(");
StringBuffer values=new StringBuffer("value(");
//获取所有的字段
Field[] fields = aClass.getDeclaredFields();
for (Field field:fields
) {
//判断属性上有没有注解
MyFiled myFiled = field.getAnnotation(MyFiled.class);
field.setAccessible(true);//暴力破解
if (myFiled==null){
sb.append(",");
sb.append(field.getName());
values.append(",");
values.append("'"+field.get(obj)+"'");
continue;
}
//是否被忽略
boolean isno = myFiled.isno();
if (isno){
continue;
}
sb.append(",");
sb.append(myFiled.value());
values.append(",");
values.append("'"+field.get(obj)+"'");
}
sb.append(")");
values.append(")");
return sb.toString()+values;
}