java基础之反射和泛型以及注解
程序员文章站
2023-12-13 15:43:10
java基础之反射和泛型以及注解
泛型擦除
泛型擦除: 泛型只在编译时期有效,编译后的字节码文件中不存在泛型信息。
声明泛型集合,集合两端类型必须...
java基础之反射和泛型以及注解
泛型擦除
泛型擦除: 泛型只在编译时期有效,编译后的字节码文件中不存在泛型信息。
声明泛型集合,集合两端类型必须一致。类型也可以用包装类型,泛型的类型必须是引用类型,不能为基本类型。
实现公用的类和方法,对公用的业务进行抽取。
泛型方法/泛型类/泛型接口
public class generictest { /** * 泛型声明,定义泛型方法 * @param <t> * @param <k> * @param t * @param k */ public <t, k> k save(t t, k k) { return null; } @test public void testmethod() throws exception { //使用泛型方法: 在使用泛型方法的时候,确定泛型的类型 save("hello", 1); } } 泛型类: public class generictest<t> @test public void testmethod() throws exception { //使用泛型方法: 在使用泛型方法的时候,确定泛型的类型 //save("hello", 1); //泛型类如何使用:在创建泛型类的时候确定 generictest<string> demo = new generictest<string>(); demo.save("hello", 1); }
泛型中的extends 和super的意义:
extends:定义list<? extends string>;传入的参数?必须是string类型的子类,否则会报错;
super:定义list<? super string>;传入的参数必须是string类型的父类,否则会报错;
type : 接口,任何类型默认的接口!
反射
反射可以在运行时期动态创建对象,获取对象的属性,方法
/** * @classname: app * @description: 反射技术 * @author lqw * @date 2016-5-13 下午01:33:55 * */ public class app { @test public void testinfo() throws exception { //类全名 string sql = "com.hbmy.reflect.demo2.admin"; //得到类的字节码 class<?> clazz = class.forname(sql); /** * 创建对象1: 通过默认构造函数创建(简写) */ admin admin = (admin) clazz.newinstance(); /** * 创建对象2: 通过无参构造器创建对象 */ constructor<?> constructors = clazz.getdeclaredconstructor(); constructors.newinstance(); /** * 创建对象3:通过有参构造器创建对象 */ constructor<?> constructor = clazz.getdeclaredconstructor(string.class); admin admin2 = (admin) constructor.newinstance("zhangsan"); // system.out.println(admin); } /** * 获取属性名称、值 * getdeclaredfields: 获取所有的包含私有的属性名称 * getfields:只能访问public的属性 */ @test public void testnameandvalue() throws exception { //类全名 string sql = "com.hbmy.reflect.demo2.admin"; //得到类的字节码 class<?> clazz = class.forname(sql); admin admin = (admin) clazz.newinstance(); // method[] methods = clazz.getmethods(); // for (method method : methods) // { // //设置强制访问 // method.setaccessible(true); // //名称 // string name = method.getname(); // system.out.println(name); // // } // field[] fields = clazz.getfields();//打印出来的结果只有money field[] fields = clazz.getdeclaredfields(); for (field field : fields) { //设置强制访问 field.setaccessible(true); //名称 string name = field.getname(); object value = field.get(admin); system.out.println(name + value); } } /** * 反射获取方法 */ @test public void testgetmethods() throws exception { //类全名 string sql = "com.hbmy.reflect.demo2.admin"; //得到类的字节码 class<?> clazz = class.forname(sql); admin admin = (admin) clazz.newinstance(); /* * 获取方法对象 */ method declaredmethod = clazz.getdeclaredmethod("getid"); /** * 调用方法 */ object return_value = declaredmethod.invoke(admin); system.out.println(return_value); method[] methods = clazz.getdeclaredmethods(); for (method method : methods) { method.setaccessible(true); string name = method.getname(); system.out.println(name); } }
注解
注解的作用
1、 告诉编译器如何去运行
2、 简化(取代)配置文件
public class app { @override public string tostring() { return super.tostring(); } @suppresswarnings({"unused","unchecked"}) public void save() { list list = null; } @deprecated public void save1() { } }
自定义注解: 通过自定义注解可以给类,字段,方法加上描述信息。
public @interface author { /** * 注解属性 * 1.修饰符为默认或者public * 2.不能有主体 * 3. 如果注解名称为value,使用的时候可以省略名称,直接给值 */ string name() default "lqw"; //带默认值得注解 int age() default 23; string remark(); }
元注解
元注解就是注解的注解
指定注解的可用范围 @target({ type, field, method, parameter, constructor, local_variable}) 注解的生命周期 /** * 元注解2: 指定注解的生命周期 * retentionpolicy.source 只在源码级别有效 * retentionpolicy.class 只在类的字节码级别有效 默认值 * retentionpolicy.runtime 只在运行时期有效 */ @retention(retentionpolicy.source)
最后总结一句:注解和反射其实不难,只要不畏惧,注解其实看看源码也就那么回事。至于反射嘛。可以这么说,无反射,则无框架,几乎所有的框架都是通过反射实现的。说白了,反射也就是通过加载类的字节码去获取类里面的方法和属性,其实框架也是这么实现的。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!