反射与框架

反射与注解

1.反射 reflect

读取类的信息:(扫描classpath路径下面的class文件 )

classpath包含以下三个位置:

  • 项目的bin目录
  • 项目里添加的jar包
  • 系统环境变量classpath指向的目录

类的三种获取方式

1. Class cls = Class.forName("my.Student");

2. Class cls = Student.class;

3. Integer a = 123;
   Class cls2 = a.getClass();

获取字段的描述

Field[] fields = cls.getDeclaredFields();//cls类里定义的属性 得到所有属性
		for(Field f : fields)
		{
			String name = f.getName();
			Type type = f.getType(); //字段类型
			int mod = f.getModifiers();//修饰符 pulic:1 private:2 ...
			System.out.println(name+ "," + type.getTypeName()+ "," + mod);
		}
Field nameField = cls.getDeclaredField("name"); //得到指定属性
getFields() //可以得到父类的属性(字段)
/*属性的访问,赋值 */
Object stu = cls.newInstance(); //仍以my.Student类为例 实例化对象stu
Field nameField = cls.getDeclaredField("name"); //得到指定属性
nameField.set(stu, "xyz"); //字段为public时,可以直接给该字段赋值
String name = (String) nameField.get(stu); //得到stu的属性name的值

获取方法描述

Method[] methods = cls.getMethods();
		for(Method m : methods)
		{
			String name = m.getName();
			Type type = m.getReturnType();
            Class[] paramTypes = m.getParameterTypes();//方法参数类型
			System.out.println(name + "方法返回值类型:" + type.getTypeName() );
		}
Method method2 = cls.getMethod(methodName, xxx.class ,xxx.class);//获取指定方法

创建实例

Object obj = cls.newInstance();//有默认的无参构造方法时

方法的调用

Class cls = Class.forName("classpath") //ex:my.Student
Object obj = cls.newInstance();
Class[] param = {double.class,double.class};//methodName方法的参数类型
Method method = cls.getMethod("methodName",param ); //通过上面方法查找方法名
Object[] argValues = {1.1,1.1};
method.invoke(obj,argValues );

返回值及类型判断

Object returnValue =  method.invoke(obj,argValues );
if(returnValue instanceof Double) 		 // object instanceof Double
    System.out.println("yes"+ returnValue);
Class ccc = returnValue.getClass();
if(ccc.isAssignableFrom(Double.class))   //object.isAssignableFrom(Double.class)
    System.out.println(2);
if(Double.class.isInstance(returnValue)) //class.isInstance(object)
    System.out.println(3);

好了,有个这么多反射基础,我们来写一个工具方法实现 pojo->json

public static JSONObject pojo2json(Object obj) throws Exception
{
    JSONObject json = new JSONObject();
    Class cls = obj.getClass(); //obj 为pojo对象 得到类
    Field[] fields = cls.getDeclaredFields(); //得到属性字段
    for(Field f:fields)
    {
        String fieldName = f.getName();
        //得到fieldName属性的 getter()方法名
        String getterName = "get" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
        Method getterMethod = cls.getDeclaredMethod(getterName);
        Object value = getterMethod.invoke(obj);
        json.put(fieldName,value);
    }
    return json;
}

那么,自己来实现下json->pojo吧!(tips:利用setter方法/直接给public属性赋值 )

Appendix

反射中常用的一些技术

1.类判断

  *  if(obj instanceof Student)	
    {
    }
  *  if(Student.class.isInstance(obj))
    {			
    }
  *  Class cls = obj.getClass();
    if(cls.isAssignableFrom(Student.class))
    {			
    }
  *  Class cls = obj.getClass();
    if(cls.equals(Student.class))
    {			
    }

2.注解 Annotation

一种配置信息,可以注册到.class文件里

@Documented
@Retention(RUNTIME)                        
public @interface Example
{
	String name();
    int type() default "1"   //默认值  
}
//默认参数,注解里只有一个值,且叫value()   ex:String value();

元注解

用于注解其它注解类的注解

@Rentention ,保留

  1. SOURCE :源代码级,不会编译到class文件中
  2. CLASS: 会被编译到class文件中,但加载时忽略
  3. RUNTIME:会被编译到class文件中,并被加载到JVM(在反射技术中必须使用此项)

@Target

  1. TYPE:可以修饰一个类、接口、枚举等
  2. FIELD:可以修饰一个属性
  3. METHOD:可以修饰一个方法

@Documented javaDoc

@Inherited 继承

java内置注解

java.lang.*

@deprecated 过时的

@override 重写

元空间

metaspace 不会被销毁 Class对象创建后放在元空间

普通对象是存在堆区的,会被GC回收

java内置注解

java.lang.*

@deprecated 过时的

@override 重写

元空间

metaspace 不会被销毁 Class对象创建后放在元空间

普通对象是存在堆区的,会被GC回收

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值