获取未知类型对象的属性通常有两种方式:

一是通过自定义注解的方式,通过获取被注解的属性从而获取属性的值,这种方式也是Spring参数注入的重要实现手段

二是通过反射获取属性的名称,通过属性名从而获取属性,这种方式在开发时是比较简便易实现的。

一、关于注解

1、自定义注解

首先定义一个@interface类型的注解接口

  1. @Target(ElementType.FIELD)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface ClassBeanId {
  1. }

元注解的作用就是负责注解其他注解。
    1.@Target,
    2.@Retention,
    3.@Documented,
    4.@Inherited     这些类型和它们所支持的类在java.lang.annotation包中可以找到。下面我们看一下每个元注解的作用和相应分参数的使用说明。

@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。
    作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
    取值(ElementType)有:
    1.CONSTRUCTOR:用于描述构造器
    2.FIELD:用于描述域
    3.LOCAL_VARIABLE:用于描述局部变量
    4.METHOD:用于描述方法
    5.PACKAGE:用于描述包
    6.PARAMETER:用于描述参数
    7.TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Retention定义了该Annotation被保留的时间长短:某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。使用这个meta-Annotation可以对 Annotation的“生命周期”限制。
    作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
    取值(RetentionPoicy)有:
    1.SOURCE:在源文件中有效(即源文件保留)
    2.CLASS:在class文件中有效(即class保留)
    3.RUNTIME:在运行时有效(即运行时保留)
注:注解的的RetentionPolicy的属性值是RUTIME,这样注解处理器可以通过反射,获取到该注解的属性值,从而去做一些运行时的逻辑处理

Annotation类型里面的参数该怎么设定:
    第一,只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型; 
    第二,参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String;
    第三,如果只有一个参数成员,最好把参数名称设为"value",后加小括号。

例如:

示例1:

自定义一个注解:

  1. @Target(ElementType.FIELD)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface ClassBeanId {
  4. public int id() default -1;
  5.  
  6. }

使用这个注解:

  1. public class ClassBean {
  2. @ClassBeanId(id = 20) //使用已定义的注解默认值为20。如果需要赋值,就需要用反射将id的值取出来并赋给当前类的id
  3. private int id;
  4.  
  5. public int getId() {
  6. return id;
  7. }
  8.  
  9. public void setId(int id) {
  10. this.id = id;
  11. }
  12.  
  13. @Override
  14. public String toString() {
  15. return "ClassBean [id=" + id + "]";
  16. }
  17.  
  18. }

定义获取该注解下的属性

  1. public static <T> void getData(T data) throws IllegalArgumentException, IllegalAccessException{
  2. int id = 0;
  3. Class clazz = data.getClass();
  4. Field[] fields = clazz.getDeclaredFields();
  5. for(Field field : fields){
  6. if(field.getAnnotation(ClassBeanId.class) != null){
  7. field.setAccessible(true);
  8. id = field.getInt(data);
  9. }
  10. System.out.println("id : "+id);
  11. }
  12. }

将对象传入该方法中,通过反射判断该对象属性是否添加了注解,从而获取该对象的id属性。

若要实现类似Spring框架中的参数注入,则需要重新定义一组方法,将注解中的参数传入对象之中,方法如下:

  1. public static <T> void getDataFromAnnotation(T data) throws IllegalArgumentException, IllegalAccessException{
  2. int id = 0;
  3. Class clazz = data.getClass();
  4. Field[] fields = clazz.getDeclaredFields();
  5. for(Field field : fields){
  6. if(field.getAnnotation(ClassBeanId.class) != null){ //判断该属性是否被注解
  7. field.setAccessible(true);
  8. ClassBeanId classBeanId = field.getAnnotation(ClassBeanId.class); //实例该注解
  9. field.setInt(data, classBeanId.id()); //获取注解的值并赋值给传入对象
  10. }
  11. }
  12. }

虽然并非严格的Spring框架的实现机制,但是原理是相同的。

二、关于反射

通过反射获取属性的名称,并对比属性命名就可以获取未知类型对象中某些属性值。这是一种比较常见的做法。

  1. public static <T> void getDataField(T data) throws IllegalArgumentException, IllegalAccessException{
  2. Class clazz = data.getClass();
  3. Field[] fields = clazz.getDeclaredFields();
  4. for(Field field : fields){
  5. String name = field.getName();
  6. if(name.equals("id")){
  7. field.setAccessible(true);
  8. field.setInt(data,29);
  9. }
  10. }
  11. }

Java获取未知类型对象的属性的更多相关文章

  1. java 获取实体类对象属性值的方法

    在java中我们要获得实体类对象的属性,一般情况是将实体类中的属性私有化,然后再对外提供get()与set()方法,然后再获取实体类对象的属性的时候先把对象new出来,再用变量名.get()的方法得到 ...

  2. freemarker获取封装类中对象的属性

    freemarker获取封装类中对象的属性 1.设计思路 (1)封装学生类 (2)创建数据模型 (3)新建student.ftl (4)运行Junit测试文件,生成HTML文件 2.封装学生类 Stu ...

  3. freemarker获取封装类中对象的属性(六)

    freemarker获取封装类中对象的属性 1.设计思路 (1)封装学生类 (2)创建数据模型 (3)新建student.ftl (4)运行Junit测试文件,生成HTML文件 2.封装学生类 Stu ...

  4. C# 不同类型对象同名属性赋值

    /// <summary> /// 不同类型对象同名属性赋值 /// </summary> /// <typeparam name="S">源类 ...

  5. C#动态设置匿名类型对象的属性

    用C#写WPF程序, 实现功能的过程中碰到一个需求: 动态设置对象的属性,属性名称是未知的,在运行时才能确定. 本来这种需求可以用 Dictionary<string, object> 实 ...

  6. 利用Java反射实现JavaBean对象相同属性复制并初始化目标对象为空的属性的BeanUtils

    有时遇到将数据传输对象转换成JSON串会将属性值为空的属性去掉,利用Java反射实现JavaBean对象数据传输对象的相同属性复制并初始化数据传输对象属性为空的属性,然后转换成JSON串 packag ...

  7. Java获取环境变量和系统属性

    Java获取服务器环境变量和JVM系统变量    当程序中需要使用与操作系统相关的变量(例如:文件分隔符.换行符)时,Java提供了System类的静态方法getenv()和getProperty() ...

  8. java获取Timestamp类型的当前系统时间

    java获取取得Timestamp类型的当前系统时间 java获取取得Timestamp类型的当前系统时间 格式:2010-11-04 16:19:42 方法1: Timestamp d = new ...

  9. Java自学-类和对象 类属性

    Java的类属性和对象属性 当一个属性被static修饰的时候,就叫做类属性,又叫做静态属性 当一个属性被声明成类属性,那么所有的对象,都共享一个值 与对象属性对比: 不同对象的 对象属性 的值都可能 ...

随机推荐

  1. C++学习笔记--友元

    C++控制对类对象私有部分的访问,在外部无法直接访问类的私有或保护成员.通常,公有类方法提供唯一的访问途径.有时这种限制太严格,不适合特定的编程问题.所以C++提供了友元这种形式,通过让函数或类成为类 ...

  2. python 中字典的操作(增、删、改、查)

    字典是另一种可变容器模型,且可存储任意类型对象,下标从0开始,最后一个为-1. 字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({}) ...

  3. oracle连接池问题

    1.数据来源. 控制台地址:172.30.252.164:7001/console 登陆: weblogic/weblogic#123数据库jdbc:oracle:thin:@172.30.252.1 ...

  4. python之路 django2

    Django请求生命周期 首先:对于所有的web框架来说本质就是一个socket服务端,浏览器是socket客户端 路由系统 在Django的urls中我们可以根据一个URL对应一个函数名来定义路由规 ...

  5. java: -source 1.6 中不支持 switch 中存在字符串

    最近在使用IDEA进行单个文件编译的时候给我报错,如题. 解决办法:将 Modules --->Sources ---> Language level 改为 7.0就ok了.

  6. .NET BETWEEN方法

    Between 值范围比较 可以判断一个值是否落在区间范围值中. public static bool Between<T>(this T me, T lower, T upper) wh ...

  7. qq第三方登录网站接口

    网站如何实现QQ登录功能 | 浏览:11029 | 更新:2013-12-05 10:09 1 2 3 4 5 6 7 分步阅读 一键约师傅 百度师傅为你的电脑系统,选一个靠谱师傅! 如果想让网站实现 ...

  8. 20145109 《Java程序设计》第九周学习总结

    JDBC 1 . DriverManager Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); 2 . ...

  9. Java对map进行排序并生成序号

    最近做的项目有这样一个需求:要求对map中的值进行排序并生成序号.如果值相等则序号不变:如果不相等序号为该数数值在所有元素中的索引.如下表所示: Key(String) Value(Float) Id ...

  10. 定制Writable类

    以IntWritable为例介绍,定制writable的步骤 //继承 WritableComparable接口(继承了writable接口和comparable接口) public class In ...