java基础之反射和泛型以及注解
java基础之反射和泛型以及注解
泛型擦除
泛型擦除:泛型只在编译时期有效,编译后的字节码文件中不存在泛型信息。
声明泛型集合,集合两端类型必须一致。类型也可以用包装类型,泛型的类型必须是引用类型,不能为基本类型。
实现公用的类和方法,对公用的业务进行抽取。
泛型方法/泛型类/泛型接口
publicclassGenericTest
{
/**
*泛型声明,定义泛型方法
*@param
*@param
*@paramt
*@paramk
*/
publicKsave(Tt,Kk)
{
returnnull;
}
@Test
publicvoidtestMethod()throwsException
{
//使用泛型方法:在使用泛型方法的时候,确定泛型的类型
save("hello",1);
}
}
泛型类:
publicclassGenericTest
@Test
publicvoidtestMethod()throwsException
{
//使用泛型方法:在使用泛型方法的时候,确定泛型的类型
//save("hello",1);
//泛型类如何使用:在创建泛型类的时候确定
GenericTestdemo=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)
 最后总结一句:注解和反射其实不难,只要不畏惧,注解其实看看源码也就那么回事。至于反射嘛。可以这么说,无反射,则无框架,几乎所有的框架都是通过反射实现的。说白了,反射也就是通过加载类的字节码去获取类里面的方法和属性,其实框架也是这么实现的。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
