java反射基础应用

反射基础

概念

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
Study注解定义

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
public @interface Study {
    String name() default  "hallo world!";
    String[]  morse();
}

User类

@Study(name="这是个类注解",morse={"1","2"})
public class User {
    @Study(name="这是个类注解",morse={"3","4"})
    private String name;
    private  int age;

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
    @Study(name="这是个方法注解",morse={"5","6"})
    public int addAge(int i){
         this.age+=i;
         return this.age;
    }
}
  • 获取类对象
     // 1.反射获取类
        User user=new User();
        Class<?> c1= user.getClass();
        Class c2=Class.forName("com.neteasy.reflact.User");
        System.out.println("1    :"+c1);
        System.out.println("2    :"+c2);
        System.out.println("3    :"+User.class);
1    :class com.neteasy.reflact.User
2    :class com.neteasy.reflact.User
3    :class com.neteasy.reflact.User

可以看出,以上方法获取到的是同一个类对象。

  • 获取类名
//2. 反射获取类name
        String c1name=c1.getName();
        String  c1SimpName=c1.getSimpleName();
        System.out.println("3    :"+c1name);
        System.out.println("4    :"+c1SimpName);
      
3    :com.neteasy.reflact.User
4    :User

一个全类名和类名。

  • 反射获取类属性
       Field[] fieds=c1.getDeclaredFields();
       user.setAge(26);
       user.setName("司马懿");
       for(Field field:fieds) {
           System.out .println(field); //这样是属性的类路径
           System.out .println(field.getName());//获取属性名
           field.setAccessible(true);
           if ("name".equals(field.getName())) {
               String name = (String) field.get(user);
               System.out.println("5    :" + name);
           } else {
               int age = (int) field.get(user);
               System.out.println("6    :" + age);
           }
       }
private java.lang.String com.neteasy.reflact.User.name
name
5    :司马懿
private int com.neteasy.reflact.User.age
age
6    :26

获取某具体对象的属性值。 其中需要注意的是为了防止类对象中的private属性在其他类中调用报错,我们需要field.setAccessible(true);将该属性设为可访问。

  • 为指定实例对象赋值
 // 4  为指定实例对象赋值
         User u= (User) c1.newInstance();
        for(Field field:fieds) {
            field.setAccessible(true);
            if ("name".equals(field.getName())) {
                field.set(u,"诸葛亮");
            }else{
                field.set(u,18);
            }
            System.out.println(field.get(u));
        }
诸葛亮
18
  • 反射获取方法并且执行
  //5 反射获取方法并执行
        Method[] m=c1.getMethods();
        for(Method m1:m){
            if(!("setName".equals(m1.getName()))){
                continue;
            }
            m1.invoke(u,"关云长");
            System.out.println(u.getName());
        }
         Method addm=c1.getDeclaredMethod("addAge", int.class);
         addm.invoke(u,2);
         System.out.println("7          :"+u.getAge());
关云长
7          :20

在获取方法时,可以通过getMethods()获取类中所有方法进行遍历,获取到自己想要的方法。也可以通过c1.getDeclaredMethod()根据方法名和参数类型获取到自己想要的方法。

  • 获取 类,属性,方法上的注解信息
 //   反射获取类的注解信息
      Study a =c1.getAnnotation(com.neteasy.reflact.Study.class);
       System.out.println("8           :"+((Study) a).name());
       String[] str=a.morse();
       for(String s:str){
           System.out.println("9       :"+s);
       }

       //   反射获取属性的注解信息
       for (Field fied : fieds) {
           Study annotation = fied.getAnnotation(Study.class);
           if(annotation==null){
               continue;
           }
           String name = annotation.name();
           System.out.println("10          :"+name);
           String[] morse = annotation.morse();
           for (String s : morse) {
               System.out.println("11          :"+s);
           }

       }

       //   反射获取方法的注解信息
       for(Method m1:m){
           Study annotation = m1.getAnnotation(Study.class);
           if (annotation ==null) {
               continue;
           }

           String name = annotation.name();
           System.out.println("12          :"+name);
           String[] morse = annotation.morse();
           for (String s : morse) {
               System.out.println("13          :"+s);
           }
       }



   }
8           :这是个类注解
9       :1
9       :2
10          :这是个类注解
11          :3
11          :4
12          :这是个方法注解
13          :5
13          :6

这样就可以通过反射获取类中的所有想知道的信息。

通过反射生成sql语句

Table注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
   String name();
}

Column注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Column {
   String name() default "";
}

Order类

@Table(name="t_order")
public class Order {
  @Column
  private String id;
  @Column(name="order_id")
  private String orderId;
  @Column(name="user_name")
  private String userName;
  @Column(name="user_id")
  private String userId;
  public String getId() {
      return id;
  }
  public void setId(String id) {
      this.id = id;
  }
  public String getOrderId() {
      return orderId;
  }
  public void setOrderId(String orderId) {
      this.orderId = orderId;
  }
  public String getUserName() {
      return userName;
  }
  public void setUserName(String userName) {
      this.userName = userName;
  }
  public String getUserId() {
      return userId;
  }
  public void setUserId(String userId) {
      this.userId = userId;
  }
}

SqlUtil类

public class SqlUtil {
  public  static  StringBuffer getSql(Object obj) throws IllegalAccessException {
      Class clz=obj.getClass();
      StringBuffer sb1=new StringBuffer();
      StringBuffer sb2=new StringBuffer();
      sb1.append("select ");
      sb2.append("where ");
      Field[] declaredFields = clz.getDeclaredFields();
      for (Field declaredField : declaredFields) {
          Column annotation = declaredField.getAnnotation(Column.class);
          declaredField.setAccessible(true);
          String column = annotation.name();
          String o = (String) declaredField.get(obj);
          if("".equals(column)){
              sb1.append("  "+declaredField.getName()+" ,");
          if(o!=null){
              sb2.append("and"+declaredField.getName()+"="+o+"  ");
          }}else{
              sb1.append(" "+column+" , ");
              if(o!=null){
                  sb2.append("and"+column+"="+o+"  ");
              }
          }
      }
      Table table= (Table) clz.getAnnotation(Table.class);
      if(table == null){
          throw new RuntimeException("缺少表名!!");
      }
      sb1.append("    from "+table.name());
      sb1=sb1.append(" "+sb2);
      return sb1;
  }
}

main

 public static void main(String[] args) {
        Order order=new Order();
        order.setUserId("1999");
        StringBuffer sb=new StringBuffer();
        try {
            sb=SqlUtil.getSql(order);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        System.out.println(sb);
    }

运行结果

select   id , order_id ,  user_name ,  user_id ,     from t_order where anduser_id=1999  

顺利完成!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值