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

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

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

一、关于注解

1、自定义注解

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

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

元注解的作用就是负责注解其他注解。
    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:

自定义一个注解:

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

使用这个注解:

public class ClassBean {
@ClassBeanId(id = 20) //使用已定义的注解默认值为20。如果需要赋值,就需要用反射将id的值取出来并赋给当前类的id
private int id; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} @Override
public String toString() {
return "ClassBean [id=" + id + "]";
} }

定义获取该注解下的属性

public static <T> void getData(T data) throws IllegalArgumentException, IllegalAccessException{
int id = 0;
Class clazz = data.getClass();
Field[] fields = clazz.getDeclaredFields();
for(Field field : fields){
if(field.getAnnotation(ClassBeanId.class) != null){
field.setAccessible(true);
id = field.getInt(data);
}
System.out.println("id : "+id);
}
}

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

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

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

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

二、关于反射

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

public static <T> void getDataField(T data) throws IllegalArgumentException, IllegalAccessException{
Class clazz = data.getClass();
Field[] fields = clazz.getDeclaredFields();
for(Field field : fields){
String name = field.getName();
if(name.equals("id")){
field.setAccessible(true);
field.setInt(data,29);
}
}
}

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. Creating an generated Earth AVI with C++

    Creating an generated Earth AVI with C++        EarthGenerator.cpp /*    EarthGenerator.cpp An examp ...

  2. mysql锁机制之间隙锁(Next-Key锁)(五)

    间隙锁(Next-Key锁) 当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的 索引项加锁:对于键值在条件范围内但并不存在的记录,叫做“间隙(GA ...

  3. 自己写个 Drools 文件语法检查工具——栈的应用之编译器检测语法错误

    一.背景 当前自己开发的 Android 项目是一个智能推荐系统,用到 drools 规则引擎,于我来说是一个新知识点,以前都没听说过的东东,不过用起来也不算太难,经过一段时间学习,基本掌握.关于 d ...

  4. eclipse中Web Deployment Assembly与build path作用

    java Build path是编译路径设置,主要用来设置源代码的编译路径默认是default output folder Web Deployment Assembly是eclipse中的发布路径设 ...

  5. HTML DOM setInterval() 方法

    定义和用法 setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式. setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被 ...

  6. JS正则表达式从入门到入土(5)—— 量词

    量词 很多时候,我们需要匹配一个连续出现很多次字符的字符串,比如,我们要匹配一个连续出现20次的数字的字符串,按照之前的写法: \d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d ...

  7. Python3.x:zip()函数

    Python3.x:zip()函数 1,概述: zip函数接受任意多个(包括0个和1个)序列作为参数,返回一个tuple列表: 2,示例: (1).示例1: x = [1, 2, 3] y = [4, ...

  8. 如何在Kubernetes集群动态使用 NAS 持久卷

    1. 介绍: 本文介绍的动态生成NAS存储卷的方案:在一个已有文件系统上,自动生成一个目录,这个目录定义为目标存储卷: 镜像地址:registry.cn-hangzhou.aliyuncs.com/a ...

  9. HBase安装过程

    1).上传,解压,重命名,修改环境变量/etc/profile 2).修改 hbase-env.sh 文件 export JAVA_HOME=/usr/java/jdk1.7.0_27 //Java ...

  10. Python-自省机制

     help 如果说能够通过一个函数就能够学会 Python,那这个函数一定就是 Python 提供的第一 个自带说明 help().help 函数的作用就是查看对象的帮组文档.比如: >> ...