您的位置:首页 > 职场人生

黑马程序员_java高级篇初识框架+Beanutil Day12

2013-12-12 16:23 302 查看
----------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! --------

黑马程序员_java高级篇初识框架+Beanutil Day12

#用反射机制做框架#

当我们写好一个类,给别人用时,不一定能用,我们怎样才能保证别人用我们类的方便性呢?

看一个例子:

还是上一篇文章的例子,不过这回我们改了。

这个config.properties文件里放了className=’java.lang.ArrayList’
Properties prop=new Properties();
BufferedInputStream br=new BufferedInputStream(new FileInputStream("config.properties"));
prop.load(br);
//告诉window关闭资源这个对象的关联的资源,自己再被回收
br.close();
String className=(String)prop.get("className");
System.out.println(className);
Collection coll=(Collection)Class.forName(className).newInstance();
Reflectpointrp=new Reflectpoint(3,3);
coll.add(rp);
coll.add(new Reflectpoint(3,4));
coll.add(new Reflectpoint(3,5));
coll.add(rp);
coll.add(new Reflectpoint(3,5));
System.out.println(coll.size());


当我们这样做的时候,我们就可以只需要改配置文件里的值,不需要修改代码了,String className=(String)prop.get("className");这个语句就是来获得我们在文件里放的java.lang.ArrayList,我们将它改为java.lang.HashSet,当获得以后,我们通过Class.forName(className).newInstance()反射得到一个对象,这样使用,比我们写死方便,同时框架中有很多也是这样写的。

#对于配置文件的纠结#

这个问题都是有这个语句引用出来的!

BufferedInputStream br=newBufferedInputStream(new FileInputStream("config.properties"));


其中文件路径我们要用绝对路径,因为我们拷贝工程给某人时,只是class文件,我们可以把文件放在src目录下,这样才能使它与类在一起。同时里也可以建立一个包resource
下面有三种方案,都可以,第三种最方便。

(一)
这样用相对路径可能找不到,但是绝对路劲也有问题,要getrealpath
BufferedInputStream br=newBufferedInputStream(new FileInputStream("config.properties"));


(二)
千万要注意路径问题,如果cn/itcast/day1/confi改为/cn/itcast也会出错

这种只可以读,因为只有返回InputStream ,上面(一)的可以写因为他有OutputStream,
br=ReflectFile.class.getClassLoader().getResourceAsStream("cn/itcast/day1/config.properties");


(三)
其实直接提供了一套方法可以使用,因为我们按上面那种要先找到那个class在加载,加载后再调用,那还不如直接用提供一个方法,这方法聪明,只需要提供文件名
InputStream br=ReflectFile.class.getResourceAsStream("config.properties");

prop.load(br);


//告诉window关闭资源这个对象的关联的资源,自己再被回收
br.close();


#内省对类的值进行设置于操作(主要对javabean进行操作)#

如下:

String propertyName="x";
Reflectpoint rp=new Reflectpoint(3,4);
PropertyDescriptor p=new PropertyDescriptor(propertyName,rp.getClass());
//Method m=;
Object retVal=p.getReadMethod().invoke(rp);
System.out.println(retVal);


x是Reflectpoint类中定义的一个属性,int x,通过PropertyDescriptor

我们可以得到操作这个对象的对象,再通过这个对象找到set(),get()方法,这样就可以完成对类的值进行设置了。

上面只是调用了getReadMethod()读方法,同时我们也要注意写方法 Methodmx=p.getWriteMethod();mx.invoke(rp,7);大家注意invoke没有,当我们调用read时,invoke只要一个参数,因为读是调用了getX(),不需要传入参数,但是写方法是调用的
SetX(),要传入一个参数。

对javabean也来了解一下,他是一个满足规则特殊的java类。

满足如下的有一个Y属性,有set与get方法的特殊类。

public int getY() {
return y;
}

public void setY(int y) {
this.y = y;
}


#BeauUtils的使用#

首先要下载两个类BeanUtils 与logging

初识Bean

BeanUtil工具更加方便的来操作对象的属性

BeanUtils.setProperty(rp,"x","9");这一个语句就可以完成上面三个语句的功能,我们注意x是int型的,为什么可以用字符串给它赋值呢,这个就是BeanUtils给我们在内部自动置换的,其实也就是将String转为int。对于另一个也可以实现同样的功能,但用这个与setProperty不一样,他的格式是非常明确的,不进行类型转换PropertyUtils.setProperty(rp,"x",9);
Beanutil+logging下载

Bean对复杂属性的操作如下:
BeanUtils.setProperty(rp,"birth.time","999");
Birth是对象rp对应类中的一个属性,当我们用想要设定birth的值时,我们要注意,

Date是不是一个简单的类型,他也是一个类,要想set时间,我们必须得到Date的方法,

Date有一个setTime()方法,根据规则对应的属性是time,所以我们在使用时先找到birth属性,再一次找到类型的方法对应的属性time。

#注解(重要的JDK1.5新特性,反射不是)#

1, 简单了解注解

注解有三种,第一是当我们想要过时的方法照样能用,还要编译器不提醒,我们加上注解@SuppressWarnings(value={""}),第二种是这个方法已经过时,但是可以用,如果直接删掉,以前的人就会报错,所以我们用这种方法比较好,这时我们用@Deprecated。第三种重载@Override。

回顾前面有一点我们要注意,就是那个hashcode与equal,我们不能把equal里面的
* Object不能改成我们的类名,如果我们改了,他就不会调用我们的方法。因为他接受的是object
* 当你以为别人或你写代码会覆盖父类的代码,怎样呢,用注解。
*

* sun公司提供的基本注解:过时deprecate,覆盖override,已过时但不要提醒supresswarning

我觉得如果把两个使用类粘贴出来,构成注解分析更好。这里面有了注释,同时我们也可以更加清晰的看到各个类的配合。

注解接口:
package JavaBean;

importjava.lang.annotation.ElementType;
importjava.lang.annotation.Retention;
importjava.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//在注解上加的注解叫元注解。
@Retention(RetentionPolicy.RUNTIME)
/*
* 分为三个阶段java源文件RetentionPolicy.SOURCE-->class文件RetentionPolicy.CLASS-->内存中的字节码RetentionPolicy.RUNTIME
* 在每一个阶段都有可能丢失
*/

//用于说明我们的注解用于哪里
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface Swaring1_1{

public String color() default "bule";
public String value();
int[] a() default {23};
test enumt() default test.MON;
MetaAnction an() default @MetaAnction(val="ds");
//  WeekDay l() default WeekDay.SUN;

}


注解使用
package JavaBean;

import sun.util.calendar.BaseCalendar.Date;
@Swaring1_1(color="red",value="green",a={1})
public class SWarning {

/**
* @param args
* jdk的新特性枚举,注解,记住反射不是
*/
//这就是注解,一个注解也是一个类,我们用了就像新建一个对象
@SuppressWarnings(value={""})
@Swaring1_1("green")
public static void main(String[] args) {
// TODO Auto-generatedmethod stub

//当我们有这种情况,提醒过时时,我们可以用注解来消除,我就是要用
//过时的
System.runFinalizersOnExit(true);

//加入元注解
if(SWarning.class.isAnnotationPresent(Swaring1_1.class))
{
Swaring1_1 sw=SWarning.class.getAnnotation(Swaring1_1.class);
System.out.println(sw.color());
}

}
//这个注解代表过时了,当我们用这个的时候,就是告诉用我们jar包的人
//这个方法已经过时,但是可以用,如果直接删掉,以前的人就会报错,所以我们
//用这种方法比较好
@Deprecated
public void show()
{
System.out.println("hihello");
}

/*
* 回顾前面有一点我们要注意,就是那个hashcode与equal,我们不能把equal里面的
* Object不能改成我们的类名,如果我们改了,他就不会调用我们的方法。因为他接受的是object
* 当你以为别人或你写代码会覆盖父类的代码,怎样呢,用注解。
*
* sun公司提供的基本注解:过时deprecate,覆盖override,已过时但不要提醒supresswarning
*/
}


----------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! --------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: