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 ...
随机推荐
- BZOJ4870: [Shoi2017]组合数问题
4870: [Shoi2017]组合数问题 Description Input 第一行有四个整数 n, p, k, r,所有整数含义见问题描述. 1 ≤ n ≤ 10^9, 0 ≤ r < k ...
- hdu 5274 树链剖分
Dylans loves tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- 2015 多校联赛 ——HDU5301(技巧)
Your current task is to make a ground plan for a residential building located in HZXJHS. So you must ...
- bzoj 1217: [HNOI2003]消防局的设立
Description 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了 ...
- [bzoj4236]JOIOJI
来自FallDream的博客,未经允许,请勿转载,谢谢. JOIOJI桑是JOI君的叔叔.“JOIOJI”这个名字是由“J.O.I”三个字母各两个构成的. 最近,JOIOJI桑有了一个孩子.JOIOJ ...
- [APIO2010]
A.特别行动队 n<=1000000 看了数据范围和题目感觉就像是斜率优化,然后瞎推了一波式子,没想到A了. sij表示i+1到j的权值和. j比k优秀 $$fj+a*sij^{2}+b*si ...
- IP地址、子网掩码、网关、DNS服务器
1. IP地址 IP是英文Internet Protocol的缩写,意思是"网络之间互连的协议",也就是为计算机网络相互连接进行通信而设计的协议.在因特网中,它是能使连接到网上的所 ...
- C++内存机制中内存溢出、内存泄露、内存越界和栈溢出的区别和联系
当我们在用C++做底层驱动的时候,经常会遇到内存不足的警告,究其原因,往往是因为内存出现溢出,泄露或者越界等原因.那么他们之间有什么联系吗? 内存溢出(out of memory) 是指程序在申请内存 ...
- python2.7入门---运算符
已经分享过变量类型的基本概念了,接下来就研究了一下运算符的基础知识.接下来我们就来看一下内容.举个简单的例子 4 +5 = 9 .例子中,4 和 5 被称为操作数,"+" ...
- Java获取随机数的3种方法
最小值---最大值(整数)的随机数 方法1 (数据类型)(最小值+Math.random()*(最大值-最小值+1)) 例: (int)(1+Math.random()*(10-1+1)) / ...