-------- android培训、java培训、期待与您交流! ----------
黑马程序员---高新技术之javabean和泛型
1、JavaBean 内省与beanutils工具包
内省(IntroSpector)主要用于对JavaBean进行操作。
JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。
用 途:如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问。
特 点:JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。去掉set和get前缀,剩余部分就是属性名。如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的。JavaBean必须有一个不带参数的构造方法。
好 处:一个符合JavaBean特点的类可以当作普通类一样进行使用,但如果把它当做JavaBean,那么就可以调用JDK提供的对专门对JavaBean进行操作的API,以实现对一些对普通类来说比较复杂的功能。
内省(IntroSpector)-->JavaBean-->特殊的java类
JavaBean这种类中方法的名字要按特定的规则来起名字。
Class Person
{
private int x;
public int getAge(){
return age;
}
public void setAge(int age);//当做javabean来看,我们说设置age属性,而不是设置x属性。
{
this.x= age;
}
}
Class Person{ private int x; public int getAge(){ return age;} public void setAge(int age);//当做javabean来看,我们说设置age属性,而不是设置x属性。{ this.x= age;}}
可以把一个javabean当做一个普通的类进行操作。
一个普通的类不一定可以当做javabean来操作(如果由get set方法就可以当做javabean来操作)。
如果把这个类当做javabean来看,那javabean的属性是根据get和set方法的名称推断出来的。而不是根据内部成员变量的名称推断出来的。
去掉set和get之后剩下的就是javabean属性名
Age-->如果第二个字母是小的,则把第一个字母变成小的-->age
gettime-->time
setTime-->time
getCPU-->CPU
把类按照javabean的方式来处理的方便之处。
JavaBean是一种特殊的类,主要用于传递数据信息,这种Java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。
在两个模块中传递多个信息,可以将这些信息封装到一个Javabean中,这种JavaBean的实例对象通常称之为值对象(Value_Object,VO)。这些信息在类中用私有字段来存储。如果读取或者设置这些字段的值,则需要通过一些相应的方法来访问。
ReflectPoint pt1 = new ReflectPoint(3,5);
String propertyName = "x";要获取的javabean的属性的名字
PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt1);//get方法没有参数。不知道返回值类型,定义成Object
Method methodSetX = pd.getWriteMethod();
methodSetX.invoke(pt1,7);//set方法接收参数
pt1.getX();
将对JavaBean的属性的Set和Get抽取成方法
private static void setProperty(Object pt1, String propertyName,
Object value) throws IntrospectionException,
IllegalAccessException, InvocationTargetException {
PropertyDescriptor pd2 = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodSetX = pd2.getWriteMethod();
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();
Object retVal = methodGetX.invoke(pt1);
return retVal;
}
2、BeanUtils工具包。
该工具包提供了设置和读取javabean属性的方法。
BeanUtils.getProperty(pt1,"x");//返回类型是字符串。
BeanUtils.setProperty(pt1,"x","9");//参数是字符串
好处1:把set和get方法的成员的类型都当做字符串来操作,完成了自动转换。
BeanUtils.setProperty(pt1,"birtyday.time","111")//Date能看成一个javabean,birtyday.time是一个复核属性。
好处2:支持属性的级联操作。
好处3:copyProperties方法把一个对象身上的属性拷贝到另一个对象身上。
可以把一个javabean的属性转换成map集合。
populate 把map集合中键值填充到javabean属性中。
Map map = {name:"zxx",age,age:18};
BeanUtils.setProperty(map,"name","lhm");//把map集合的name属性的值改为"lhx";
PropertyUtils.setProperty(pt1,"x",9);//这里的9要写x属性的本来类型。不想进行类型转换就用这个
3、泛型
引入泛型的原因之一:在使用集合时,可以向定义好的某一集合中存入任意类型的数据,而我们希望整个集合中的类型都是一样的,当加入的不期望的类型后,只有到运行期才能发现。 而且取出的类型需要强制转换。
ArrayList collection = new ArrayList();
collection.add(1);
collection.add(1L);
collection.add("abc");
// int i = (Integer)collection.get(1);//这句会报错
//使用泛型的代码:
// 在集合中的应用
ArrayList<String> collection1 = new ArrayList<String>();
// collection1.add(1);
// collection1.add(1L);
collection1.add("String");
String i = collection1.get(0);// 在反射中的应用
//用反射实现操作:String str = new String(new StringBuffer("abc"));
Constructor<String> constructor1 = String.class.getConstructor(StringBuffer.class);
String str1 = constructor1.newInstance(new StringBuffer("abc"));
System.out.println(str1.charAt(2));
从上面两段代码的对比中,很容易看出使用泛型的好处:1.限定了集合元素的类型;2.省去了强制转换的过程。
JDK升级一般可分为三个大的方面:1.简化书写;2.提高效率;3.提高安全性。而泛型就属于其中的第三方面安全,它是一种安全机制。
(1)泛型集合类的综合应用案例
HashMap<String,Integer> hm = new HashMap<String,Integer>();
hm.put("zyq", 18);
hm.put("zsy", 49);
hm.put("zyx", 25);
Set<Map.Entry<String,Integer>> entrySet = hm.entrySet();
for(Map.Entry<String, Integer> entry:entrySet){
System.out.println(entry.getKey() + ":" + entry.getValue());
}
(2)自定义泛型类
import java.util.Set;
//dao data access object:CRUD
public class GenericDao<E> {
//增
public void add(E x){
}
//删
public void delete(int id){
}
public void delete(E obj){
}
//查
public E findByID(int id){
return null;
}
public E findByName(String name){
return null;
}
public Set<E> findByConditions(String where){
return null;
}
//改
public void update(E obj){
}
public static<E> void update1(E obj){//静态方法不能用类上定义的泛型参数,但可以自己定义泛型,这里的E和类上的E是两码事。
}
}
(3)通过反射获得泛型的参数化类型
没办法通过泛型的引用,用反射获取参数化类型的类型参数。 但可以通过反射获得方法的参数列表,从参数列表中获取参数化类型(ParameterizedType)的原始类型(RawType)和实际类型参数(ActualTypeArguments)
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.Vector;
class GenericTest {
public static void main(String[] args) throws Exception{
Method applyMethod = GenericTest.class.getMethod("applyVector", Vector.class);
Type[] types =applyMethod.getGenericParameterTypes();
ParameterizedType pType =(ParameterizedType) types[0];
System.out.println(pType.getClass());
System.out.println(pType.getOwnerType());
System.out.println(pType.getRawType());
System.out.println(pType.getActualTypeArguments()[0]);
}
public static void applyVector(Vector<Date> v){
}
/*
public static void applyVector(Vector<Integer> v){ //这个方法和上边的方法是同一个方法。
}*/
}