- 浏览: 587808 次
- 性别:
- 来自: 福建
文章分类
最新评论
-
18335864773:
用 pageoffice 吧. http://www.zhuo ...
使用Jacob输出word文档 -
dick1305:
很好,谢谢分享。
XFire创建WebService实例 -
wd530141534:
<c:if test="${ReleaseRe ...
Axis2创建WebService实例 -
wd530141534:
if(result != null && re ...
Axis2创建WebService实例 -
wd530141534:
String printerIp = req.getRemot ...
Axis2创建WebService实例
一、 Java反射
1.Java反射是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs
取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等)、
superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields和methods的所有信息,
并可于运行时改变fields内容或唤起methods。
2.获取类的Class对象的几种方式:
(1)类名.class。例:Boolean.class。
(2)对象.getClass()。例:new Date().getClass();
(3)Class.forName(“类名”);例:Class.forName("java.util.Date");
3.Constructor(获取类的构造方法)
(1)得到某个类的所有构造方法。例:
Constructor []constructors = Class.forName("java.lang.String").getConstructors();
(2)得到某个类的某一个构造方法。例:
Constructor constructor = Class.forName("java.lang.String") .getConstructo(StringBuffer.class);
(3)利用默认的构造方法创建Class对象所表示的类的新实例。例:
String str = (String)Class.forName("java.lang.String").newInstance();
4.Field(获取类的成员变量)
(1)getField(""), 获取指定名称的公共成员变量。
(2)getFields(),获取所有的公共成员变量。
(3)getDeclaredField(“”),获取指定名称的声明变量,包含私有的。
(4)getDeclaredFields(),获取所有的声明变量,包含私有的。
示例代码如下:
Order order = new Order(Long.parseLong("1001"), "订单1", Double.parseDouble("150.80")); order.setName("1001"); // 获取成员变量Id,getField("")获取的成员变量必须是公共成员变量,否则抛异常。 Field field = order.getClass().getField("id"); // 获取成员变量name,getDeclaredField("")获取声明的所有成员变量,包含私有的。 Field field2 = order.getClass().getDeclaredField("name"); // 私有成员变量需采用暴力反射才能访问应用。 field2.setAccessible(true); System.out.println(field2.get(order));
注意:获取到的成员变量是类上面的,而不是对象上的,可通过成员变量.get(实例对象)获取到指定实例对象的成员变量值。
5.Method(获取类中的成员方法)
(1)getMethod(String name, Class<?>... parameterTypes),获取指定方法名称和参数类型的公共成员方法。
(2)getMethods(),获取所有的公共成员方法。
(3)getDeclaredMethod(String name,Class<?>... parameterTypes),
获取指定方法名称和参数类型的声明成员方法,包含私有成员方法在内。
(4)getDeclaredMethods(),获取所有声明的成员方法,包含私有成员方法在内,但不包括继承的方法。
示例代码如下:
Method substring = Class.forName("java.lang.String") .getMethod("substring", int.class); String strAt = (String) substring.invoke(str, 3); // 获取私有的成员方法 Method getHello = order.getClass().getDeclaredMethod("getHello"); // 私有成员方法需暴力反射才能访问调用 getHello.setAccessible(true); // 实例对象为null,表示该方法是static方法。 System.out.println(getHello.invoke(null));
6.其它说明
(1)基本类型的一维数组可以被当做Object类型使用,不能当作Object[]类型使用,
非基本类型的一维数组既可以被当做Object类型使用,又可以当作Object[]类型使用。
(2)框架与工具类的区别在于,工具类被用户的类调用,而框架则是调用用户提供的类,
由于在设计框架时无法知道用户提供的类,无法实例化具体的对象,需采用反射的方式来实现。
二、内省
1、内省是 Java 语言对 Bean 类属性、事件的一种缺省处理方法。
也就是说给定一个javabean对象,我们就可以得到/调用它的所有的get/set方法。
例如类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新的值。
通过 getName/setName 来访问 name 属性,这就是默认的规则。
Java 中提供了一套 API 用来访问某个属性的 getter/setter方法,
通过这些API可以使你不需要了解这个规则,这些API存放于包java.beans中。
例:通过类 Introspector 来获取某个对象的 BeanInfo信息,然后通过 BeanInfo来
获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性
对应的 getter/setter 方法,然后我们就可以通过反射机制来调用这些方法。
Order order = new Order(); order.setName( "ZX001" ); //如果不想把父类的属性也列出来的话,那getBeanInfo的第二个参数填写父类的信息 BeanInfo bi = Introspector.getBeanInfo(order.getClass(), Object.class); PropertyDescriptor[] props = bi.getPropertyDescriptors(); for(int i=0;i<props.length;i++){ System.out.println(props[i].getName()+ "=" + props[i].getReadMethod().invoke(order, null )); }
2、Apache的commons包封装了很多对Java对象的基本操作,例如BeanUtils,PropertyUtils等,
可使用其对Java对象进行操作。
三、 注解
1、注解相当于一种标记,注解可以加在包,类,字段,方法,方法的参数以及局部变量上。
注解使得Java源代码中不但可以包含功能性的实现代码,还可以添加元数据。注解的功能类似于代码中的注释,
所不同的是注解不是提供代码功能的说明,而是实现程序功能的重要组成部分。
2、java1.5起默认的三个annotation类型:
一个是@Override:只能用在方法之上的,用来告诉别人这一个方法是改写父类的。
一个是@Deprecated:建议别人不要使用旧的API的时候用的,编译的时候会用产生警告信息,
可以设定在程序里的所有的元素上.
一个是@SuppressWarnings:这一个类型可以来暂时把一些警告信息消息关闭.
3、自定义注解类(@interface)
* RetentionPolicy.RUNTIME 内存中的字节码 * RetentionPolicy.SOURCE Java源文件 * RetentionPolicy.CLASS Class文件 */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD,ElementType.TYPE}) public @interface MyAnnotation { // 注解属性(注解属性也可以是数组,枚举,注解等) String color() default "blue"; String value(); }
@Retention用于描述注解的生命周期:
SOURCE代表的是这个Annotation类型的信息只会保留在程序源码里,源码如果经过了编译之后,
Annotation的数据就会消失,并不会保留在编译好的.class文件里面。
ClASS的意思是这个Annotation类型的信息保留在程序源码里,同时也会保留在
编译好的.class文件里面,系统默认值是CLASS.
RUNTIME,表示在源码、编译好的.class文件中保留信息,在执行的时候会把这一些信息加载到JVM中去的.
@Target用于描述注解的使用范围:
TYPE(类型), FIELD(属性), METHOD(方法), PARAMETER(参数), CONSTRUCTOR(构造函数),
LOCAL_VARIABLE(局部变量), ANNOTATION_TYPE,PACKAGE(包),
其中的TYPE(类型)是指可以用在Class,Interface,Enum和Annotation类型上.
4、注解类的反射调用,例:
@MyAnnotation(value = "test") public class MyAnnotationTest { public static void main(String []args){ // 判断是否加上MyAnnotation类型的注解 if(MyAnnotationTest.class.isAnnotationPresent(MyAnnotation.class)){ MyAnnotation annation = MyAnnotationTest.class.getAnnotation(MyAnnotation.class); System.out.println(annation.color()+"#####"+annation.value()); } } }
四、 泛型
1.泛型(Generic type或者generics)是对Java语言的类型系统的一种扩展,以支持创建可以按类型
进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数
是运行时传递的值的占位符一样。
好处:泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,
编译器可以在一个高得多的程度上验证类型假设。将类型检查从运行时挪到编译时有助于您更容易找到错误,
并可提高程序的可靠性。
泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。
2.Java编译器编译生成的字节码会去掉泛型的类型信息,只要能通过编译器,就能往某个泛型集合中
加入其它类型的数据。事例代码如下:
public static void main(String[] args) throws Exception{ ArrayList<Integer> collection1=new ArrayList<Integer>(); collection1.add(1); collection1.add(2); collection1.add(3); collection1.getClass().getMethod("add", Object.class).invoke(collection1, "abcdefg"); System.out.println(collection1.get(3)); }
3.泛型相关术语:
ArrayList<E>,泛型类型。
ArrayList<E>中的E称为类型变量或类型参数。
ArrayList<Integer>称为参数化的类型。
ArrayList<Integer>中的Integer称为类型参数的实例或实际类型参数。
ArrayList<Integer>中的<>称为typeof。
ArrayList称为原始类型。
参数化类型与原始类型可相互引用,但会出现警告。例:
Map<String,String> map = new HashMap(); Map map = new HashMap<String,String>();
参数化类型不考虑类型参数的继承关系,例:
Map<String,String> map= new HashMap<String,Object>();//编译器错误
数组元素不能使用参数化的类型,可通过Array.newInstance(Classtype,int size)的方式来创建数组。
4.泛型通配符?
使用?通配符可以引用其它各种参数化的类型,?通配符定义的变量主要用作引用,可以调用与参数化无关的方法,
不能调用与参数化有关的方法。例:
public static void printCollection(Collection<?> cols){ for(Object col:cols){ System.out.println(col); } //cols.add("hello");// 编译错误,?通配符不能调用与参数化有关的方法 cols.size();// ?通配符可以调用与参数化无关的方法 cols = new HashSet<Date>();// 引用通配符可以引用各种其它参数化的类型 }
(1) 限定通配符的上边界
// 正确 List<? extends Number> list= new ArrayList<Integer>(); // 错误 List<? extends Number> list2= new ArrayList<String>();
(2)限定通配符的下边界
// 正确 List<? super Integer> list= new ArrayList<Number>(); // 错误 List<? super Integer> list2= new ArrayList<Byte>();
5、泛型方法
例:
static <E> void swap(E[] a,int i,int j){ E t = a[i]; a[i]= a[j]; a[j] = t; }
(1)用于放置泛型的类型参数的尖括号应出现在方法的其它所有修饰符之后和方法的返回类型之前,
也就是紧邻返回值之前。类型参数通常用单个大写字母表示。
(2)只有引用类型才能作为泛型方法的实际参数,swap(new int[3],3,5)会报编译错误。
(3)泛型不仅在应用时可以使用extends限定符,在定义泛型时也可以使用extends限定符,
并且可以用&来指定多个边界,如<E extends Serializable & Cloneable> void method(){}
(4)泛型也可以用类型变量来表示异常,称为参数化的异常,也可以用于方法的throws列表中,但不能用于catch子句中。
(5)在泛型中可以同时有多个类型参数,在定义它们的尖括号中用逗号分开,例:
public static <K,V> V getValues(K key){}
6.类型参数的类型推断
编译器判断泛型方法的实际参数的过程称为类型推断。根据调用泛型方法时实际传递的参数类型或返回类型来推断,具体规则如下:
(1)当某个类型变量只在整个参数列表中的所有参数和返回值中的一处被应用了,那么根据调用方法时该处的实际应用
类型来确定。例:swap(new String[3],3,4)->static<E> void swap(E[] a,int i,int j)
(2)当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时多处的实际应用类型都
对应同一种类型,则根据实际应用类型来确定。例:add(3,5)->static<T> T add(T a,T b)
(3)当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时多处的实际应用类型
对应到了不同的类型,且没有返回值,这时取多个参数中的最大交集类型。例:下面语句对应的类型就是Number了。
Fill(new Integer[3],3.5f)->static<T> void fill(T[] a,T v)
(4)当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时多处的实际应用类型
对应到了不同的类型,并且使用返回值,这时优先考虑返回值的类型,例如,下面语句实际对应的类型就是Integer了,
编译器报告错误,将变量类型改为float,对比编译器的错误提示,再将变量类型改为Number。
(5)参数类型的类型推断具有传递性(a=c,b=c推出a=b),下面第一种情况推断实际参数类型为Object,
编译没问题,而第二种情况则根据参数化的Vector类实例将类型变量直接确定为String类型,编译将出现问题:
copy(new Integer[5],new String[5])-->static <T> void copy(T[] a,T[] b)
copy(new Vector<String>(),new Integer[5])-->static <T> void copy(Collection<T> a,T[] b)
7、泛型类型
(1)如果类的实例对象中的多处都要用到同一个泛型参数,这时采用泛型类型的方式进行定义,也就是类级别的泛型。
以下示例为将方法级别的泛型改进为类级别的泛型:例:
public class GenericDao { public <T> void save(T po){} public <T> T getById(String id){return null;} }
改进为:
public class GenericDao<T> { public T field1; public void save(T po){} public T getById(String id){return null;} }
(2)类级别的泛型是根据引用该类名时指定的类型信息来参数化类型变量的,以下两种方式都可以:
GenericDao<String> dao = null; new GenericDao<String>();
(3)在对泛型类型进行参数化时,类型参数的实例必须是引用类型,不能是基本类型。当一个变量被声明为泛型时,
只能被实例变量和方法调用,不能被静态变量和静态方法调用。
8、利用反射获得泛型的参数化类型
public class GenericReflection { private Vector<Date> dates = new Vector<Date>(); public void setDates(Vector<Date> dates) { this.dates = dates; } public static void main(String args[]){ Method []methods = GenericReflection.class.getMethods(); for(Method method:methods){ if(method.getName().equals("setDates")){ ParameterizedType paramType = (ParameterizedType) method.getGenericParameterTypes()[0]; // 获得参数类型 System.out.println(((Class)paramType.getRawType()).getName()); // 获得泛型的参数化类型 System.out.println(((Class)paramType.getActualTypeArguments()[0]).getName()); } } } }
发表评论
-
JAVA多线程事例参考(二)
2013-05-10 16:15 1148一、JAVA多线程之Lock import j ... -
JAVA多线程事例参考(一)
2013-05-10 16:07 1367一. Java多线程安全问题,模拟银行存款 /** * ... -
JAVA之 IO流
2013-01-16 13:57 1558一、IO流流就是字节序列的抽象概念,能被连续读取数据的数 ... -
CXF创建WebService实例
2013-01-07 20:33 18040一、概述1、ApacheCXF项目是由ObjectWeb Ce ... -
JAVA编程指南
2012-12-27 22:57 1114一、设计方法论 1、 ... -
JAVA基础
2012-12-27 22:43 1296一、JAVA基础 1.类的构建过程是从基类“向外”扩散 ... -
Java类加载器入门应用
2012-03-08 22:40 23821、类加载器负责加载 Ja ... -
CAS单点登录应用
2012-02-15 17:33 1950一. 基础知识点1.CAS Se ... -
Freemarker模板应用
2012-01-11 17:13 43766FreeMarker是一个模板引擎,一个基于模板生成文 ... -
Velocity模板应用
2011-12-14 19:25 18044Velocity是一个基于java的模板引擎(模板引擎的作用就 ... -
XFire创建WebService实例
2011-11-16 13:58 61986XFire创建WebService实例应用 X ... -
Axis2创建WebService实例
2011-03-26 14:34 193139一、Axis2的下载和安装 1.可从http: ... -
Maven使用小结
2011-01-08 21:52 11806(1)创建一个maven项目 mvn archetype ... -
Tomcat部署Web应用
2010-12-16 22:28 14681.利用Tomcat自动部署 将myWeb应用目录拷贝 ... -
Tomcat数据源配置
2010-12-16 21:32 1277一、 Tomcat5.0.X数据源配置,修改${tomca ...
相关推荐
完整版 Java高级教程 Java语言程序设计 第1章 输入输出流(共42页).ppt 完整版 Java高级教程 Java语言程序设计 第2章 Java多线程(共24页).ppt 完整版 Java高级教程 Java语言程序设计 第2章 哲学家的故事(共7页)...
完整版 Java高级教程 Java语言程序设计 第1章 输入输出流(共42页).ppt 完整版 Java高级教程 Java语言程序设计 第2章 Java多线程(共24页).ppt 完整版 Java高级教程 Java语言程序设计 第2章 哲学家的故事(共7页)...
Java技术水平也将逐渐与世界同步 1.1 Java的诞生和发展规律 1.2 与C和C++语言的异同 1.3 Java平台 ......
通过学习本书的内容,将为读者以后学习Java语言的各种高级应用打下坚实的基础。 本书实用性强,由浅入深,适合作为高等院校计算机及相关专业的教材和培训用书。同时,本书也是广大Java爱好者学习Java程序设计,Java...
Android平台的应用开发用到Java开发语言,算是对Java语言的扩展应用,所以精通Java对学习和应用android程序很有帮助,这里就是Java的高级应用
编程语言java高级应用.pdf
Java高级应用程序综合实训_具体实施过程.pdfJava高级应用程序综合实训_具体实施过程.pdfJava高级应用程序综合实训_具体实施过程.pdfJava高级应用程序综合实训_具体实施过程.pdfJava高级应用程序综合实训_具体实施...
JAVA_3 JAVA语言基础 位运算 JAVA_3 JAVA语言基础 JAVA_4 Java面向对象特性 JAVA_5 高级语言特征 JAVA_6 异常处理Exceptions JAVA_7 IO输入输出 JAVA_8 AWT图形界面编程 JFC AWT Swing JAVA_8 AWT图形界面编程 JFC ...
完整版 杭州电子科技大学JAVA语言程序设计 JAVA_05 高级语言特征(共65页).ppt 完整版 杭州电子科技大学JAVA语言程序设计 JAVA_06 异常处理Exceptions(共31页).ppt 完整版 杭州电子科技大学JAVA语言程序设计 JAVA...
Java高级应用程序综合实训_具体实施过程.docxJava高级应用程序综合实训_具体实施过程.docxJava高级应用程序综合实训_具体实施过程.docxJava高级应用程序综合实训_具体实施过程.docxJava高级应用程序综合实训_具体...
完整版 杭州电子科技大学JAVA语言程序设计 JAVA_05 高级语言特征(共65页).ppt 完整版 杭州电子科技大学JAVA语言程序设计 JAVA_06 异常处理Exceptions(共31页).ppt 完整版 杭州电子科技大学JAVA语言程序设计 JAVA...
本书是Java语言的经典教材 ,中文版分为基础篇和进阶篇,主要介绍程序设计基础、面向对象程序设计、GUI程序设计、数据结构和算法 、高级Java程序设计等内容。本书以示例讲解解决问题的技巧,提供大量的程序清单,每...
本书是Java语言的经典教材,中文版分为基础篇和进阶篇,主要介绍程序设计基础、面向对象程序设计、GUI程序设计、数据结构和算法、高级Java程序设计等内容。本书以示例讲解解决问题的技巧,提供大量的程序清单,每章配...
完整版 杭州电子科技大学JAVA语言程序设计 JAVA_05 高级语言特征(共65页).ppt 完整版 杭州电子科技大学JAVA语言程序设计 JAVA_06 异常处理Exceptions(共31页).ppt 完整版 杭州电子科技大学JAVA语言程序设计 JAVA...
完整版 杭州电子科技大学JAVA语言程序设计 JAVA_05 高级语言特征(共65页).ppt 完整版 杭州电子科技大学JAVA语言程序设计 JAVA_06 异常处理Exceptions(共31页).ppt 完整版 杭州电子科技大学JAVA语言程序设计 JAVA...
Java高级应用.ppt
基础篇(原书第8版)》是Java语言的经典教材,中文版分为《Java语言程序设计基础篇》和《Java语言程序设计进阶篇》,主要介绍程序设计基础、面向对象程序设计、gui程序设计、算法和数据结构、高级java程序设计等内容。...
Java基础入门教程 第2章 java语言基础(共52页).ppt Java基础入门教程 第3章 类和对象(共40页).ppt Java基础入门教程 第4章 继承和多态(共36页).ppt Java基础入门教程 第5章 Java基础类的应用(共42页).ppt ...
1.1.1.Java 语言有哪些特点? 1.1.2.关于 JVM JDK 和 JRE 最详细通俗的解答 1.1.2.1.JVM 1.1.2.2.JDK 和 JRE 1.1.3.Oracle JDK 和 OpenJDK 的对比 1.1.4.Java 和 C++的区别? 1.1.5.什么是 Java 程序的主类 应用程序和...