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)


 最后总结一句:注解和反射其实不难,只要不畏惧,注解其实看看源码也就那么回事。至于反射嘛。可以这么说,无反射,则无框架,几乎所有的框架都是通过反射实现的。说白了,反射也就是通过加载类的字节码去获取类里面的方法和属性,其实框架也是这么实现的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值