java反射注解

------- android培训java培训、期待与您交流! ----------

反射
概念:


Java反射机制是在运动状态中,对于任意一个类都能知道这个类的所有属性和方法。
对于任意一个对象都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。


简单说:反射就是将Java类中的各种成分映射成相应的java类。


反射的基石:
Class 类
代表java类,对应的各个类在内存中的字节码,类加载到内存,在内存空间里内容就是类的字节码,一个个空间分别用一个个对象来表示,对象有相同的类型。


得到字节码对应的实例对象方法(Class类型)
1,类名.class:
System.class
任何数据类型都具备的静态属性
2,对象.getClass:
new Date().getClass()
Object中的getClass方法


3,通过给定的类的字符串名称使用Class.forName()方法类获取该类:
Class.forName("java.util.Date")




八个基本类型和void,
有九种预定义的 Class实例对象,八个基本类型和 void。这些类对象由 Java 虚拟机创建,与其表示的基本类型同名,即 boolean、byte、char、short、int、long、float 和 double。 
基本类型的字节码获取方式只有一种就是类名.class。例如int.class;void.class




这些对象仅能通过下列声明为 public static final 的变量访问,也是使此方法返回 true 的仅有的几个 Class 对象。


Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE


数组类型的Class实例对象
Class.isArray()
只要是在源程序中出现的类型,都有各自的Class实例对象。


反射就是把Java类中的各种成分映射成相应的Java类。
Construtor类代表某个类中的一个构造函数
通过Constructor类getConstructors()获取的是构造方法。或者指定参数得到指定方法。


Constructor[]constructors= Class.forName("java.lang.String").getConstructor();得到类中所有构造方法。


反射创建实例对象时,调用获取的方法要用到上面相同类型的实例对象。
要类型强转。


Filed类:成员变量


ReflectPoint pt1 = new ReflectPoint(3,5);


Field fieldY = pt1.getClass().getField("y");//反射公有成员
filedY不是对象身上的变量,而是类上的,要用它取出某个对象的值。
fieldY.get(pt1);//获取pt1的公有成员
Filed fieldX = pt1.getClass().getDeclaredField("x");//反射私有
fieldX.setAccessible(true);//准许获得私有成员
fieldX.get(pt1)//pt1对象的x
反射和暴力反射
改变对象成员的值,b 变成 a
Field[] fields = obj.getClass().getFields();
for(Field field : fields)
{
if(field.getType() == String.class)//字节码用==
{
String oldValue = (String)field.get(obj);
String newValue = oldValue.replace('b','a');
field.set(obj,newValue);
}
}




Method类
获取类的方法,可以用来调用指定对象的方法。


Method methodCharAt = String.class.getNethod("charAt",int.class);
//通过String类的str1对象获取String类中的charAt方法
methodCharAt.invoke(str1,1);
//使用String的对象调用charAt方法


调用main方法
String startingClassName = args[0];
Method mainMethod = Class.forName(startingClassName).getMethod("main",Strin[].class);
mainMethod.invoke.(null,(Object)new String{"34","34","56"});
//1.5数组会自动拆包:打2个包,或者是变成对象
methodcharAt.invoke(null,1);//如果调用一个方法第一个参数是null,说明这个方法是静态的。




数组反射


有相同维数和元素类型的数组属于同一个类型,即具有相同Class实例对象。
代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class。
基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用,非基本类型的一维数组,可以当成Object类型和Object[]类型
Arrays.asList()对int[]自动装箱成一个对象,String[]作为数组
Array工具类用于完成对数组的反射操作。


使用反射技术开发框架的原理:


反射的作用
实现框架功能:因为在写程序时无法知道要被调用的类名,所以在程序中无法直接new某个实例对象,要用反射方式来获取。


框架与工具类的区别,工具类被用户的类调用,而框架则是调用用户提供的类。




用类加载器的方式管理资源和配置文件:


开发时要使用绝对路径,但是绝对路径不是硬编码,应该是运算出来的。


1.使用io读取流读取。


InputStream ips = new FileInputStream("路径");


2.使用类加载器加载。


InputStream ips = ReflectPoint.class.getClassLoaderAsStream("路径");//路径不能以/打头


类提供的简便方法加载:
InputStream ips = ReflectPoint.class.getResourceAsStream("name");//用相对路径的话是相对于ReflectPoint包所在目录即可,也可以用绝对路径这时需要/打头。




*****
注解:




注解就是标注相当于一种标记,就像学生的胸卡,加上了注解就为程序打上了标记。
编译器,开发工具和其他程序来操作类和各种元素的时候可以根据注解做对应的处理。


JDK的内置注解:




JDK中内置了三个注解分别为:@Override、@Depressed和@SuppressWarnings。
@Override:主要用于子类在覆盖父类方法时,检测方法时候正确,如果是覆盖父类方法,没有提示,否则编译器会报错。


@Depressed:主要使用在:程序在更新升级的时候出现新方法替代了老方法,如果去掉老方法的话调用老方法的类会报错,为了兼容以前的类,同时要提醒新设计的类不建议使用老方法,这时就在老方法上加上@Depressed注解。


@SuppressWarnings:压缩警告,主要用于屏蔽警告,比如已经过时的警告。


@SuppressWarnings的取值如下:


deprecation,使用了过时的类或方法时的警告   
unchecked,执行了未检查的转换时的警告  
fallthrough,当 Switch 程序块直接通往下一种情况而没有 Break 时的警告 
path,在类路径、源文件路径等中有不存在的路径时的警告  
serial,当在可序列化的类上缺少serialVersionUID 定义时的警告  
finally ,任何 finally 子句不能正常完成时的警告  
all,关于以上所有情况的警告


注解的反射:


Class类中的方法isAnnotationPresent(Class<? extends Annotation> annotationClass)和isAnnotation()方法可以判断这个Class上是否有注解。


可通过getAnnotation(Class<? extends Annotation> annotationClass)方法获取注解。




元注解:元注解是在注解内部中使用的注解


@Retention


@Retention存活三个时期:


   1.RetetionPolicy.SOURCE(源文件)


   2.RetetionPolicy.CLASS(class文件)


   3.RetetionPolicy.RUNTIME(内存中的字节码)


@Target用于标明标记可以加在的成分上(包,类,枚举,注解,接口,字段,方法,构造方法、方法的参数上和局部变量上)


注解属性:


结合代码和注释来说明注解属性


自定义注解类:


import java.lang.annotation.ElementType;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)//注解保存到字节码 
@Target({ElementType.METHOD,ElementType.TYPE})//注解可以加在方法上和类型上
public @interface ItcastAnnotation 
{  
	String color() default "blue";//default设置缺省值 
	String value();//如果只有一个value属性需要设置,value=可以省略
	int[] arrayAttr() default {1,2,3};//数组类型的属性 
	TrafficLamp lamp() default TrafficLamp.RED;
	MateAnnotation annotationAttr() default @MateAnnotation("lhm");
}

应用了注解的类,和主函数中对注解进行反射的类:
01.@ItcastAnnotation(color="red",value="abc",arrayAttr={3,4,5},annotationAttr=@MateAnnotation("flx"))  
public class AnnotationDemo 
{
	@ItcastAnnotation("ab")//如果注解中有一个名称为value的属性,且只想设置value属性,可以省略value=部分
	public static void main(String[] args)
	{
		if(AnnotationDemo.class.isAnnotationPresent(ItcastAnnotation.class))
		{
			ItcastAnnotation annotation = AnnotationDemo.class.getAnnotation(ItcastAnnotation.class);
			System.out.println(annotation.color());//red
			System.out.println(annotation.value());//abc
			System.out.println(annotation.arrayAttr().length);//3 
			System.out.println(annotation.lamp().nextLamp().name());//GREEN
			System.out.println(annotation.annotationAttr().value());//flx
		}
	}
}

-------  android培训 java培训 、期待与您交流! ----------



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值