内省的简单运用:

JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。



采用遍历BeanInfo的所有属性方式来查找和设置某个RefectPoint对象的x属性。在程序中把一个类当作JavaBean来看,就是调用IntroSpector.getBeanInfo方法, 得到的BeanInfo对象封装了把这个类当作JavaBean看的结果信息。

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Date;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;

/**
 * 内省的简单运用。
 * @author hjl
 *
 */
public class IntroSpectorTest {

	public static void main(String[] args) throws Exception {

		ReflectPoint pt1=new ReflectPoint(3, 5);
		String propertyName="x";
		//"x"--->"X"-->"getX"--->"MethodGexX"-->
		Object retVal = getProperty(pt1, propertyName);
		System.out.println(retVal);

		Object value =7;
		setProperties(pt1, propertyName, value);

		System.out.println(BeanUtils.getProperty(pt1,"x").getClass());

		BeanUtils.setProperty(pt1, "x", "9");

		System.out.println(pt1.getX());

		//java7新特性
		/*
		Map<K, V> map=(name:"hjl",age:18);
		BeanUtils.setProperty(map, "name", "lhm");
		*/
		BeanUtils.setProperty(pt1,"birthday.time", "111");

		System.out.println(BeanUtils.getProperty(pt1, "birthday.time"));

		PropertyUtils.setProperty(pt1,"x", 9);
		System.out.println(PropertyUtils.getProperty(pt1, "x").getClass());
	}

	private static void setProperties(Object pt1, String propertyName,
			Object value) throws IntrospectionException,
			IllegalAccessException, InvocationTargetException {
		PropertyDescriptor pd2=new  PropertyDescriptor(propertyName, pt1.getClass());
		Method methodSetX=pd2.getWriteMethod();//得到属性的get方法。
		methodSetX.invoke(pt1,value);
	}

	private static Object getProperty(Object pt1, String propertyName)
			throws IntrospectionException, IllegalAccessException,
			InvocationTargetException {
//		PropertyDescriptor pd=new  PropertyDescriptor(propertyName, pt1.getClass());
//		Method methodGetX=pd.getReadMethod();//得到属性的get方法。
//		Object retVal=methodGetX.invoke(pt1);
//		return retVal;

		BeanInfo beanInfo=Introspector.getBeanInfo(pt1.getClass());
		PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors();
		Object retVal=null;
		for(PropertyDescriptor pd:pds){
			if(pd.getName().equals(propertyName)){
				Method methodGetX=pd.getReadMethod();
				retVal=methodGetX.invoke(pt1);
				break;
			}
		}

		return retVal;
	}
}



注解:

通过System.runFinalizersOnExit(true);的编译警告引出@SuppressWarnings("deprecation") 

@Deprecated

直接在刚才的类中增加一个方法,并加上@Deprecated标注,在另外一个类中调用这个方法。

@Override

public boolean equals(Reflect other)方法与HashSet结合讲解

总结:

注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,以后,javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事。标记可以加在包,类,字段,方法,方法的参数以及局部变量上。

看java.lang包,可看到JDK中提供的最基本的annotation。 

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

//元注解
//元数据
//元信息
@Retention(RetentionPolicy.RUNTIME)//注解的注解,是为这个注解服务的。
//这个让注解保留在运行阶段
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface Annotation {

	String color() default "blue";
	String value();
	int [] arrayAttr() default {3,4,4};
	EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.Red;
	MetaAnnotation annotationAttr() default @MetaAnnotation("ssh");
}

自定义注解及其应用:

/**
 *
 * @author hjl
 *
 */
@Annotation(annotationAttr=@MetaAnnotation("ssID"), color="red",value="haha",arrayAttr=1)
public class AnnotationTest {

	@SuppressWarnings("deprecation")
	//@Annotation("haha")
	public static void main(String[] args) throws Exception {
		System.runFinalizersOnExit(true);
		//对一个类进行检查,利用反射
		if(AnnotationTest.class.isAnnotationPresent(Annotation.class)){
			Annotation annotation=(Annotation) AnnotationTest.class.getAnnotation(Annotation.class);
			//为什么用type,因为type中包含了class,type中有许多class
			//这个类的实例对象是通过反射找到的。
			System.out.println(annotation);
			System.out.println(annotation.color());
			System.out.println(annotation.arrayAttr().length);
			System.out.println(annotation.lamp().nextLamp());
			System.out.println(annotation.annotationAttr().value());
		}
	}

	//对于那些过时的方法,我们可以进它进行注解,以便编译器还能编译
	@Deprecated //表示过时
	public static void sayHello(){
		System.out.println("hello,world!");
	}
}

泛型:

泛型中的通配符,?

使用?通配符可以引用其他各种参数化的类型,?通配符定义的主要用作引用,可以引用调用与参数化无关的方法,不能调用与参数化有关的方法。

泛型的实例又是一个带参数化的类型。



在定义泛型的时候,也可以限定类型,同时可以定义多个接口。

用下面的代码说明对异常如何采用泛型:


private static <T extends Exception> sayHello() throws T

{

try{

}catch(T|e){

throw(T)e;

}



}

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import day01.ReflectPoint;

public class GenericTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		ArrayList collection1 = new ArrayList();
		collection1.add(1);
		collection1.add(1L);
		collection1.add("abc");
		//int i = (Integer)collection1.get(1);

		ArrayList<String> collection2 = new ArrayList<String>();
		//collection2.add(1);
		//collection2.add(1L);
		collection2.add("abc");
		String element = collection2.get(0);	

		//new String(new StringBuffer("abc"));
		Constructor<String> constructor1 = String.class.getConstructor(StringBuffer.class);
		String str2 = constructor1.newInstance(/*"abc"*/new StringBuffer("abc"));
		System.out.println(str2.charAt(2));		

		ArrayList<Integer> collection3 = new ArrayList<Integer>();
		System.out.println(collection3.getClass() == collection2.getClass());
		//collection3.add("abc");
		collection3.getClass().getMethod("add", Object.class).invoke(collection3, "abc");
		System.out.println(collection3.get(0));

		printCollection(collection3);

		//Class<Number> x = String.class.asSubclass(Number.class);
		Class<?> y;
		Class<String> x ;//Class.forName("java.lang.String");

		HashMap<String,Integer> maps = new HashMap<String, Integer>();
		maps.put("zxx", 28);
		maps.put("lhm", 35);
		maps.put("flx", 33);

		Set<Map.Entry<String,Integer>> entrySet = maps.entrySet();
		for(Map.Entry<String, Integer> entry : entrySet){
			System.out.println(entry.getKey() + ":" + entry.getValue());
		}

		add(3,5);
		Number x1 = add(3.5,3);//前面为什么是Number,因为float,int的交集是Number
		Object x2 = add(3,"abc");

		swap(new String[]{"abc","xyz","itcast"},1,2);
		//swap(new int[]{1,3,5,4,5},3,4);//泛型的类型,只能是引用类型,不能是基本类型
		//只有引用类型才能作为泛型方法的实际参数。这是基于自动装箱,拆箱的功能,
		//本身如果就是基本类型的话,本身如果要的就是这种基本类型的话,如果装箱的话,就是多此一举了
		Object obj = "abc";
		String x3 = autoConvert(obj);

		copy1(new Vector<String>(),new String[10]);
		copy2(new Date[10],new String[10]);
		//copy1(new Vector<Date>(),new String[10]);//类型摧断具有传播性

		GenericDao<ReflectPoint> dao = new GenericDao<ReflectPoint>();
		dao.add(new ReflectPoint(3,3));
		//String s = dao.findById(1);

		//Vector<Date> v1 = new Vector<Date>();
		Method applyMethod = GenericTest.class.getMethod("applyVector", Vector.class);
		Type[] types = applyMethod.getGenericParameterTypes();
		ParameterizedType pType = (ParameterizedType)types[0];
		System.out.println(pType.getRawType());
		System.out.println(pType.getActualTypeArguments()[0]);
	}

	public static void applyVector(Vector<Date> v1){

	}

	private static <T> void fillArray(T[] a,T obj){
		for(int i=0;i<a.length;i++){
			a[i] = obj;//定义一个方法,可以将任意类型的数组中的所有元素填充为相应类型的某个对象。
		}
	}
	private static <T> T autoConvert(Object obj){
		return (T)obj;//定义一个泛型方法,自动将Object类型的对象转变成其他类型。
	}
	private static <T> void swap(T[] a,int i,int j){
		T tmp = a[i];
		a[i] = a[j];
		a[j] = tmp;
	}

	private static <T> T add(T x,T y){
		//声明了一个新的类型,T x,T y是把T这种类型的变量与另一个T类型的变量进行相加
		//返回的结果还是T这种类型的结果。在返回值之前,我们用<>来说明这种类型
		return null;
	}

	public static void printCollection(Collection<?> collection){
		//collection.add(1);
		System.out.println(collection.size());
		for(Object obj : collection){
			System.out.println(obj);
		}
	}

	public static <T> void printCollection2(Collection<T> collection){
		//collection.add(1);
		System.out.println(collection.size());
		for(Object obj : collection){
			System.out.println(obj);
		}

	}

	public static <T> void copy1(Collection<T> dest,T[] src){
		//定义一个方法,把任意参数类型的集合中的数据安全地复制到相应类型的数组中。
		for(int i=0;i<src.length;i++){
			dest.add(src[i]);
		}
	}

	public static <T> void copy2(T[] dest,T[] src){
		//定义一个方法,把任意参数类型的一个数组中数据安全复制到相应类型的另一个数组中。
	}
}

普通方法,构造方法和静态方法都可以定义泛型。

也可以用类型变量表示异常,称为参数化的异常,可以用于throws列表中,但是不能用于catch子句中。

import java.util.Set;

//dao data access object--->crud
public class GenericDao<E>  {
	public void add(E x){

	}

	public E findById(int id){
		return null;
	}

	public void delete(E obj){

	}

	public void delete(int id){

	}	

	public void update(E obj){

	}

	public static <E> void update2(E obj){

	}

	public E findByUserName(String name){
		return null;
	}
	public Set<E> findByConditions(String where){
		return null;
	}
}

Java基础---Java---基础加强---内省的简单运用、注解的定义与反射调用、 自定义注解及其应用、泛型及泛型的高级应用、泛型集合的综合的更多相关文章

  1. Android面试基础(一)IOC(DI)框架(ViewUtils)讲解_反射和自定义注解类

    1. Android中的IOC(DI)框架 1.1 ViewUtils简介(xUtils中的四大部分之一) IOC: Inverse of Controller 控制反转. DI: Dependenc ...

  2. java 利用反射完成自定义注解

    元注解: 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明.Java5.0定义的元注解: 1.@ ...

  3. java 编程基础:注解的功能和作用,自定义注解

    1,什么是注解: 从JDK5开始,Java增加了对元数据 (MetaData)的支持,也就是Annotation注解,这种注解与注释不一样,注解其实是代码里的特殊标记,这些标记可以在编译.类加载 运行 ...

  4. Java反射与自定义注解

    反射,在Java常用框架中屡见不鲜.它存在于java.lang.reflact包中,就我的认识,它可以拿到类的字段和方法,及构造方法,还可以生成对象实例等.对深入的机制我暂时还不了解,本篇文章着重在使 ...

  5. Java 扫描实现 Ioc 动态注入,过滤器根据访问url调用自定义注解标记的类及其方法

    扫描实现 Ioc 动态注入 参考: http://www.private-blog.com/2017/11/16/java-%e6%89%ab%e6%8f%8f%e5%ae%9e%e7%8e%b0-i ...

  6. [原创]Java使用反射及自定义注解实现对象差异性比较

    Java项目C中 有一处逻辑,对于资源数据(类型为ResourceItem,拥有int/double/boolean/String类型数十个字段),需要比对资源数据每次变更的差异,并描述出变更情况.并 ...

  7. Java基础笔记 – Annotation注解的介绍和使用 自定义注解

    Java基础笔记 – Annotation注解的介绍和使用 自定义注解 本文由arthinking发表于5年前 | Java基础 | 评论数 7 |  被围观 25,969 views+ 1.Anno ...

  8. java 编程基础:【注解】 提取注解信息,利用自定义注解编写测试类,注解绑定事件

    提取注解信息 使用注解修饰了类.方法.成员变量等成员之后,这些注解不会自己生效,必须由开发者提供相应工具来提取并处理注解信息.   Java使用java.lang.annotation.Annotat ...

  9. java基础知识:自定义注解

    转自 深入了解注解 要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法. 元注解的作用就是负责注解其他注解.J ...

随机推荐

  1. ●BZOJ 2119 股市的预测

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2119 题解: 这个题很好的. 首先把序列转化为差分序列,问题转化为找到合法的子序列,使得去除 ...

  2. SpringCloud学习之SpringCloudBus

    一.spring-cloud-bus是什么? 回答这个问题之前,我们先回顾先前的分布式配置,当配置中心发生变化后,我们需要利用spring-boot-actuator里的refresh端点进行手动刷新 ...

  3. SpringCloud学习之快速搭建分布式配置

    一. 关于spring-cloud中的分布式配置 Spring Cloud Config为分布式系统中的外部配置提供服务器和客户端支持.使用Config Server,您可以在所有环境中管理应用程序的 ...

  4. Linux 基本概念和操作

    我们在使用Linux时,不是直接和系统打交道,而是通过shell的中间程序.在图形界面下为了实现窗口的输入和输出,linux系统为我们提供了终端模拟器Terminal,常见的终端模拟器有 gnome- ...

  5. JAVA解析XML文件(DOM,SAX,JDOM,DOM4j附代码实现)

    1.解析XML主要有四种方式 1.DOM方式解析XML(与平台无关,JAVA提供,一次性加载XML文件内容,形成树结构,不适用于大文件) 2.SAX方式解析XML(基于事件驱动,逐条解析,适用于只处理 ...

  6. sqlserver 截取字符串(转)

    SQL Server 中截取字符串常用的函数: 1.LEFT ( character_expression , integer_expression ) 函数说明:LEFT ( '源字符串' , '要 ...

  7. 使用RestTemplate访问restful服务时遇到的问题

    可以通过通过wireshark抓包,使用Postman发送请求 wireshark是非常流行的网络封包分析软件,功能十分强大.可以截取各种网络封包,显示网络封包的详细信息.使用wireshark的人必 ...

  8. css修改浏览器默认的滚动条样式

    //滚动条样式 ::-webkit-scrollbar { width: 10px; } /* 垂直滚动条的滑动块 */ ::-webkit-scrollbar-thumb:vertical { bo ...

  9. PAT-013 L1-013. 计算阶乘和

    L1-013. 计算阶乘和 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 对于给定的正整数N,需要你计算 S = 1! + 2 ...

  10. Python3 JSON 数据解析

    JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. Python3 中可以使用 json 模块来对 JSON 数据进 ...