Java基础---Java---基础加强---内省的简单运用、注解的定义与反射调用、 自定义注解及其应用、泛型及泛型的高级应用、泛型集合的综合
内省的简单运用:
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---基础加强---内省的简单运用、注解的定义与反射调用、 自定义注解及其应用、泛型及泛型的高级应用、泛型集合的综合的更多相关文章
- Android面试基础(一)IOC(DI)框架(ViewUtils)讲解_反射和自定义注解类
1. Android中的IOC(DI)框架 1.1 ViewUtils简介(xUtils中的四大部分之一) IOC: Inverse of Controller 控制反转. DI: Dependenc ...
- java 利用反射完成自定义注解
元注解: 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明.Java5.0定义的元注解: 1.@ ...
- java 编程基础:注解的功能和作用,自定义注解
1,什么是注解: 从JDK5开始,Java增加了对元数据 (MetaData)的支持,也就是Annotation注解,这种注解与注释不一样,注解其实是代码里的特殊标记,这些标记可以在编译.类加载 运行 ...
- Java反射与自定义注解
反射,在Java常用框架中屡见不鲜.它存在于java.lang.reflact包中,就我的认识,它可以拿到类的字段和方法,及构造方法,还可以生成对象实例等.对深入的机制我暂时还不了解,本篇文章着重在使 ...
- 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 ...
- [原创]Java使用反射及自定义注解实现对象差异性比较
Java项目C中 有一处逻辑,对于资源数据(类型为ResourceItem,拥有int/double/boolean/String类型数十个字段),需要比对资源数据每次变更的差异,并描述出变更情况.并 ...
- Java基础笔记 – Annotation注解的介绍和使用 自定义注解
Java基础笔记 – Annotation注解的介绍和使用 自定义注解 本文由arthinking发表于5年前 | Java基础 | 评论数 7 | 被围观 25,969 views+ 1.Anno ...
- java 编程基础:【注解】 提取注解信息,利用自定义注解编写测试类,注解绑定事件
提取注解信息 使用注解修饰了类.方法.成员变量等成员之后,这些注解不会自己生效,必须由开发者提供相应工具来提取并处理注解信息. Java使用java.lang.annotation.Annotat ...
- java基础知识:自定义注解
转自 深入了解注解 要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法. 元注解的作用就是负责注解其他注解.J ...
随机推荐
- [bzoj1063][Noi2008]道路设计
来自FallDream的博客,未经允许,请勿转载,谢谢. Z国坐落于遥远而又神奇的东方半岛上,在小Z的统治时代公路成为这里主要的交通手段.Z国共有n座城市,一些城市之间由双向的公路所连接.非常神奇的是 ...
- bzoj1010[HNOI2008]玩具装箱toy 斜率优化dp
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 11893 Solved: 5061[Submit][S ...
- Mysq 索引优化
MYSQL支持的索引类型 BTREE索引 特点: 通过引用以B+权的结构存储数据 能够加快数据的查询速度 更适合进行范围查找 应用: 全值匹配的查询 = 匹配最左前缀的查询 匹配列前缀查询 LIKE ...
- JS 实现点击页面任意位置隐藏div、span
通过调用下面的 showhidden(“标签ID”) 显示div/span/…等标签内容,可以实现点击页面任意地方再次隐藏该标签内容,而showhidden(“标签ID”,”nohidden”)可保存 ...
- Windows、Unix、Linux是什么类型的操作系统?
Windows:具有图形用户界面的视窗操作系统. Unix:多用户分时操作系统. Linux:类似Unix操作系统,用于个人计算机.
- Android编写点击TextView拨打电话
在任何一个电商平台都会有点击了手机号码会拨打出一个电话 那么高如何实现这个功能,我们下来分析下原理 当我们点击了一个电话号码后,会弹出一个Dialog显示是否拨打次电话号码,点击确定拨打号码,点击取消 ...
- 利用Python进行数据分析——Numpy基础:数组和矢量计算
利用Python进行数据分析--Numpy基础:数组和矢量计算 ndarry,一个具有矢量运算和复杂广播能力快速节省空间的多维数组 对整组数据进行快速运算的标准数学函数,无需for-loop 用于读写 ...
- Clojure新手入门
官方网站 clojure.org 环境安装 Java(JDK) Leiningen 编辑工具 Eclipse插件 -- Counterclockwise IntelliJ插件 -- Cursive E ...
- 这是一个测试,测试markdown语法
[TOC] 1. chpt1 这是一段话,前面没有空格 前面有4个空格,且在编辑状态下上面没有空行 前面有4个空格,且在编辑状态下上面有一个空行. 前面按了一下tab 1.1 1.1 2 段落1 前面 ...
- 2016-wing的年度总结
大神们都爱写总结,为了早日成为大神,我也来写一波. 2016 有很多事情发生. 从日常生活来讲,生活水平得到了一定提升,从600一个月的村子搬到了800一个月的村子(/捂脸); 从就业环境来讲,许多人 ...