@version 1.0 2011.01.12
6,内省(Introspection)、JavaBean
→JavaBean get/set
配置文件机制 由类加载器加载,(存放于classpath)
完整路径(计算 getRealPath()+内部路径完整路径计算 getRealPath()+内部路径)
//InputStream ips =
ReflectTest2.class.getClassLoader().
getResourceAsStream("cn/itcast/day1/config.properties");
//InputStream ips =
ReflectTest2.class.getResourceAsStream("resources/config.properties");
InputStream ips =
ReflectTest2.class.
getResourceAsStream("/cn/itcast/day1/resources/config.properties");
Properties props = new Properties();
props.load(ips);
ips.close();
String className = props.getProperty("className");
→内省的方法读取类的属性值
public static void main(String [] args) throws Exception{
ReflectPoint pt1 = new ReflectPoint(3,5); //JavaBean对象
String propertyName = "x";
PropertyDescriptor pd =
new PropertyDescriptor(propertyName,pt1.getClass());
Method methodGetX = pd.getReadWrite();
Object retVal = methodGetX.invoke(pt1);
Method methodSetX = pd.getWriteWrite();
methodSetX.invoke(pt1,7);
System.out.println(pt1.getX());
}
→Eclipse重构
→BeanUtils (apache)
getProperty、setProperty
/* //java7的新特性
Map map = {name:"zxx",age:18}; //定义map内容
BeanUtils.setProperty(map, "name", "lhm"); //对map操作
*/
PropertyUtils (属性类型不转换)
7,注解 Annotation
→@SuppressWarnings("deprecation") //编译过滤过时警告
→@Deprecated //标记过时
→@override //标记重写
包、类、成员变量、参数、局部变量都可以注解
→注解的应用
@interface A{}
@A
Class B{}
Class C{
B.class.isAnnotionPresent(A.class);
A a = B.class.getAnnotion(A.class);
}
→元注解
→@Retention(RetentionPolicy.RUNTIME)——(CLASS/RUNTIME/SOURCE)
@Override(SOURCE)、@SuppressWarnings(SOURCE)、@Deprecated(RUNTIME)
→@Target(ElementType.METHOD)、
@Target({ElementType.METHOD,ElementType.TYPE})
→注解的定义的反射调用以及为注解增加属性
import java.lang.reflect.Method;
import javax.jws.soap.InitParam;
@ItcastAnnotation(
annotationAttr=@MetaAnnotation("flx"),
color="red",value="abc",arrayAttr=1)
public class AnnotationTest {
@SuppressWarnings("deprecation")
@ItcastAnnotation("xyz")
public static void main(String[] args) throws Exception{
System.runFinalizersOnExit(true);
if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class)){
//反射调用
ItcastAnnotation annotation = (ItcastAnnotation)AnnotationTest.class.
getAnnotation(ItcastAnnotation.class);
//注解属性
System.out.println(annotation.color());
System.out.println(annotation.value());
System.out.println(annotation.arrayAttr().length);
System.out.println(annotation.lamp().nextLamp().name());
System.out.println(annotation.annotationAttr().value());
}
Method mainMethod = AnnotationTest.class.
getMethod("main", String[].class);
ItcastAnnotation annotation2 = (ItcastAnnotation)mainMethod.
getAnnotation(ItcastAnnotation.class);
System.out.println(annotation2.value());
}
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import cn.itcast.day1.EnumTest;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItcastAnnotation {
String color() default "blue";
String value();
int[] arrayAttr() default {3,4,4};
EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.RED;
MetaAnnotation annotationAttr() default @MetaAnnotation("lhm");
}
8,泛型【36-43】
→泛型(参数化类型)对于集合类尤其有用,增强可读性、避免频繁强制类型转换和不安全类型转换等;
泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用。
eg:Map<String, String> m = new HashMap<String, String>(); //附加的类型安全
→泛型提供给javac编译器使用,编译完成将去掉泛型信息(运用反射将绕过泛型定义)
→参数化类型不考虑类型参数的继承关系
→数组实例创建时,数组的元素不能使用参数化的类型
→通配符类型(wildcard type)、(extends、super关键字——上边界、下边界)
“?”代表未知类型,这个类型实现Collection了接口。
1、如果只指定了<?>,而没有extends,则默认是允许Object及其下的任何Java类了。也就是任意类。
2、通配符泛型不单可以向下限制,如<? extends Collection>,还可以向上限制,如<? super Double>,
表示类型只能接受Double及其上层父类类型,如Number、Object类型的实例。
3、泛型类定义可以有多个泛型参数,中间用逗号隔开,还可以定义泛型接口,泛型方法。
→泛型方法
是否拥有泛型方法,与其所在的类是否泛型没有关系。要定义泛型方法,只需将泛型参数列表置于返回值前。
使用泛型方法时,不必指明参数类型,编译器会自己找出具体的类型。泛型方法除了定义不同,调用就像普通方法一样。
需要注意,一个static方法,无法访问泛型类的类型参数,所以,若要static方法需要使用泛型能力,必须使其成为泛型方法。
→eg
例子一:使用了泛型
public class Gen<T> {
private T ob; //定义泛型成员变量
public Gen(T ob) {
this.ob = ob;
}
public T getOb() {
return ob;
}
public void setOb(T ob) {
this.ob = ob;
}
public void showType() {
System.out.println("T的实际类型是: " + ob.getClass().getName());
}
}
public class GenDemo {
public static void main(String[] args){
//定义泛型类Gen的一个Integer版本
Gen<Integer> intOb=new Gen<Integer>(88);
intOb.showType();
int i= intOb.getOb();
System.out.println("value= " + i);
System.out.println("----------------------------------");
//定义泛型类Gen的一个String版本
Gen<String> strOb=new Gen<String>("Hello Gen!");
strOb.showType();
String s=strOb.getOb();
System.out.println("value= " + s);
}
}
例子二:没有使用泛型
public class Gen2 {
private Object ob; //定义一个通用类型成员
public Gen2(Object ob) {
this.ob = ob;
}
public Object getOb() {
return ob;
}
public void setOb(Object ob) {
this.ob = ob;
}
public void showTyep() {
System.out.println("T的实际类型是: " + ob.getClass().getName());
}
}
public class GenDemo2 {
public static void main(String[] args) {
//定义类Gen2的一个Integer版本
Gen2 intOb = new Gen2(new Integer(88));
intOb.showTyep();
int i = (Integer) intOb.getOb();
System.out.println("value= " + i);
System.out.println("---------------------------------");
//定义类Gen2的一个String版本
Gen2 strOb = new Gen2("Hello Gen!");
strOb.showTyep();
String s = (String) strOb.getOb();
System.out.println("value= " + s);
}
}
运行结果:
两个例子运行Demo结果是相同的,控制台输出结果如下:
T的实际类型是:
java.lang.Integer
value= 88
----------------------------------
T的实际类型是: java.lang.String
value= Hello Gen!
Process finished with exit code 0
→另《java泛型详解》from http://blog.csdn.net/zkdemon/archive/2008/01/14/2043503.aspx
→HashMap、Map.Entry(条目)
----------------------------------
HashMap<String,Integer> maps = new HashMap<String, Integer>();
maps.put("zxx", 28);
maps.put("lhm", 35);
maps.put("flx", 33);
//HashMap的泛型实际参数类型是一个参数化的类型
Set<Map.Entry<String,Integer>> entrySet = maps.entrySet();
for(Map.Entry<String, Integer> entry : entrySet){
System.out.println(entry.getKey() + ":" + entry.getValue());
}
→自定义泛型
private static <T> void swap(T[] a,int i,int j){
T tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
swap(new String[]{"abc","xyz","itcast"},1,2); //交换"xyz"、"itcast"
//swap(new int[]{1,3,5,4,5},3,4); //报错,泛型的参数类型不能是基本类型,只能是引用类型
→类型推断
→throws异常使用泛型
→泛型方法
----------------------------------
private static <T> T autoConvert(Object obj){
return (T)obj;
}
String x3 = autoConvert(obj); //
----------------------------------
private static <T> void fillArray(T[] a,T obj){
for(int i=0;i<a.length;i++){
a[i] = obj;
}
}
----------------------------------
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,T obj2){
//collection.add(1);
System.out.println(collection.size());
for(Object obj : collection){
System.out.println(obj);
}
collection.add(obj2);
}
----------------------------------
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){//拷贝数组到数组
for(int i=0;i<src.length;i++){
dest[i] = src[i];
}
}
copy1(new Vector<String>(),new String[10]);
copy2(new Date[10],new String[10]); //类型推断Object
//copy1(new Vector<Date>(),new String[10]); //报错,Vector传播为Date,无法和String再进行类型推断
→类型推断总结【41,12:30】
→泛型类型(类)
----------------------------------
import java.util.Set;
public class GenericDao<E> { //crud
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;
}
}
----------------------------------
GenericDao<ReflectPoint> dao = new GenericDao<ReflectPoint>();
dao.add(new ReflectPoint(3,3));
//String s = dao.findById(1); //类型约束
→通过反射获得泛型的实际类型参数
//例如webservice返回集合内容未知类型确定,难度是上文所说的“去类型化”,(Hibernate框架实现的方法)。
----------------------------------
public static void applyVector(Vector<Date> v1){
}
----------------------------------
//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()); //class java.util.Vector
System.out.println(pType.getActualTypeArguments()[0]);
//class java.util.Date
----------------------------------