java基础之反射和泛型以及注解
java基础之反射和泛型以及注解
泛型擦除
泛型擦除:泛型只在编译时期有效,编译后的字节码文件中不存在泛型信息。
声明泛型集合,集合两端类型必须一致。类型也可以用包装类型,泛型的类型必须是引用类型,不能为基本类型。
实现公用的类和方法,对公用的业务进行抽取。
泛型方法/泛型类/泛型接口
publicclassGenericTest { /** *泛型声明,定义泛型方法 *@param*@param *@paramt *@paramk */ public Ksave(Tt,Kk) { returnnull; } @Test publicvoidtestMethod()throwsException { //使用泛型方法:在使用泛型方法的时候,确定泛型的类型 save("hello",1); } } 泛型类: publicclassGenericTest @Test publicvoidtestMethod()throwsException { //使用泛型方法:在使用泛型方法的时候,确定泛型的类型 //save("hello",1); //泛型类如何使用:在创建泛型类的时候确定 GenericTest demo=newGenericTest (); demo.save("hello",1); }
泛型中的extends和super的意义:
Extends:定义List;传入的参数?必须是String类型的子类,否则会报错;
Super:定义List;传入的参数必须是String类型的父类,否则会报错;
Type:接口,任何类型默认的接口!
反射
反射可以在运行时期动态创建对象,获取对象的属性,方法
/** *@ClassName:App *@Description:反射技术 *@authorlqw *@date2016-5-13下午01:33:55 * */ publicclassApp { @Test publicvoidtestInfo()throwsException { //类全名 Stringsql="com.hbmy.reflect.demo2.Admin"; //得到类的字节码 Class>clazz=Class.forName(sql); /** *创建对象1:通过默认构造函数创建(简写) */ Adminadmin=(Admin)clazz.newInstance(); /** *创建对象2:通过无参构造器创建对象 */ Constructor>constructors=clazz.getDeclaredConstructor(); constructors.newInstance(); /** *创建对象3:通过有参构造器创建对象 */ Constructor>constructor=clazz.getDeclaredConstructor(String.class); Adminadmin2=(Admin)constructor.newInstance("zhangsan"); //System.out.println(admin); } /** *获取属性名称、值 *getDeclaredFields:获取所有的包含私有的属性名称 *getFields:只能访问public的属性 */ @Test publicvoidtestNameAndValue()throwsException { //类全名 Stringsql="com.hbmy.reflect.demo2.Admin"; //得到类的字节码 Class>clazz=Class.forName(sql); Adminadmin=(Admin)clazz.newInstance(); //Method[]methods=clazz.getMethods(); //for(Methodmethod:methods) //{ ////设置强制访问 //method.setAccessible(true); ////名称 //Stringname=method.getName(); //System.out.println(name); // //} //Field[]fields=clazz.getFields();//打印出来的结果只有money Field[]fields=clazz.getDeclaredFields(); for(Fieldfield:fields) { //设置强制访问 field.setAccessible(true); //名称 Stringname=field.getName(); Objectvalue=field.get(admin); System.out.println(name+value); } } /** *反射获取方法 */ @Test publicvoidtestGetMethods()throwsException { //类全名 Stringsql="com.hbmy.reflect.demo2.Admin"; //得到类的字节码 Class>clazz=Class.forName(sql); Adminadmin=(Admin)clazz.newInstance(); /* *获取方法对象 */ MethoddeclaredMethod=clazz.getDeclaredMethod("getId"); /** *调用方法 */ Objectreturn_value=declaredMethod.invoke(admin); System.out.println(return_value); Method[]methods=clazz.getDeclaredMethods(); for(Methodmethod:methods) { method.setAccessible(true); Stringname=method.getName(); System.out.println(name); } }
注解
注解的作用
1、告诉编译器如何去运行
2、简化(取代)配置文件
publicclassApp { @Override publicStringtoString() { returnsuper.toString(); } @SuppressWarnings({"unused","unchecked"}) publicvoidsave() { Listlist=null; } @Deprecated publicvoidsave1() { } }
自定义注解:通过自定义注解可以给类,字段,方法加上描述信息。
public@interfaceAuthor { /** *注解属性 *1.修饰符为默认或者public *2.不能有主体 *3.如果注解名称为value,使用的时候可以省略名称,直接给值 */ Stringname()default"lqw"; //带默认值得注解 intage()default23; Stringremark(); }
元注解
元注解就是注解的注解
指定注解的可用范围 @Target({ TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) 注解的生命周期 /** *元注解2:指定注解的生命周期 *RetentionPolicy.SOURCE只在源码级别有效 *RetentionPolicy.CLASS只在类的字节码级别有效默认值 *RetentionPolicy.RUNTIME只在运行时期有效 */ @Retention(RetentionPolicy.SOURCE)
最后总结一句:注解和反射其实不难,只要不畏惧,注解其实看看源码也就那么回事。至于反射嘛。可以这么说,无反射,则无框架,几乎所有的框架都是通过反射实现的。说白了,反射也就是通过加载类的字节码去获取类里面的方法和属性,其实框架也是这么实现的。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!