Java基础加强(一)
一、JavaBean
1.JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要 用于访问私有的字段,且方法名符合某种命名规则。
如果要在两个模块之间传递多个信息,可以将信息封装在一个JavaBean中,这种JavaBean的实例对象称之为值对象。JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。
Eg:setId()的属性名---------id
isLast()的属性名-------last
setCPU的属性名-------CPU
GetUPS的属性名-------UPS
2.JDK提供了对JavaBeanin进行操作的一些API,这套API称为内省。
3.简单内省操作取得或设置成员变量值:
假设类ReflectPoint中有两个变量x,y,获取x的值
ReflectionPoint pt=new ReflectionPoint(3,5);//定义ReflectionPoint类的实例对象pt
String name=”x”;//定义变量name表示成员变量x
PropertyDescriptor pd=new PropertyDescriptor(name,pt.getClass());
Method methodGetX=pd.getReadMethod();//使x可读
Object obj=methodGetX.invoke(pt);//获取x
4.复杂的内省操作取得或设置成员变量值:
假设类ReflectPoint中有两个变量x,y,获取x的值
ReflectionPoint pt=new ReflectionPoint(3,5);//定义ReflectionPoint类的对象pt
String PropertyName=”x”;//定义变量PropertyName表示x
BeanInfo beanInfo=IntroSpector.getBeanInfo(pt.getClass());//把Java类当成JavaBean处理
PropetyDescriptor[] pds=beanInfo.getPropertyDescriptors();//得到属性集合
for(PropetyDescriptor pd:pds)//遍历pds
{
if(pd.getName.equals(PropertyName))//假设属性值为x
{
Method methodGetX=pd.getReadMethod();//使x可读
Object retVal=methodGetX.invoke(pt);//获取x的值
break;
}
}
return retVal;//返回x的值
5.通过BeanUtils获取和设置成员变量
Eg:BeanUtils.getProperty(pt,”x”);//获取pt对象的成员变量x的值
BeanUtils.setProperty(pt,”y”,”9”);//设置成员变量y的值为9
Eg:PropetyUtils.setProperty(pt,”y”,9);
PropertyUtils.getProperty(pt,“x”);
BeanUtils与PropertyUtils的区别:BeanUtils是以字符串形式对JavaBean进行操作,PropertyUtils是以属性本身的类型进行操作
二.注解
1.注解相当于一种标记,加了注解就等于打上了某种标记,没加,则等于没有某种标记。
2.常见注解:@Override(覆盖标记),@SuppressWarnings(抑制警告)以及@Deprecated(过时,建议不再使用标记)
3.@Retention元注解有三种取值:
RetentionPolicy.SOURCE/RetentionPolicy.Class/RetentionPolicy.RUNTIME对应:java源文件,class文件,内存中的字节码
4.@Target(ElementType.METHOD,ElementType.Type)//注解既可以加在类上也可以加在方法上
5.注解的属性使用
public @interface ItcastAnnocation {
String value();//定义属性value
String color();//定义属性color
int[] array();//定义数组属性array
// 定义枚举属性
EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.RED;
MetaAnnotation ARR() default @MetaAnnotation("123");}//定义注解的属性
使用:
@ItcastAnnocation(value="123",color="red",array= {1,2,3},lamp=EnumTest.TrafficLamp.GREEN,ARR=@MetaAnnotation("111"))
三、泛型
1.泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器编辑带有类型说明的集合时会去除掉”类型信息”,使程序运行效率不受影响。
2.整个ArrayList<E>称之为泛型类型;<E>称为类型变量或类型参数;ArrayList<Integer>称为参数化的类型,<Integer>称为类型参数的实例或实际类型参数,<>念typeof,ArrayList称为原始类型
3.参数化类型与原始类型的兼容性
参数类型可以引用一个原始类型的对象,编辑报告警告
Collection<String> c=new Vector();
原始类型可以引用一个参数化类型的对象,编译报告警告:
Collection c=new Vector<String>();
4.参数化类型不考虑类型参数的继承关系
Vector<String> v=new Vector<Object>();//false
Vector<Object> v=new Vector<String>();//false
5.在创建数组实例时,数组的元素不能使用参数化的类型。
Eg:Vector<Integer> vectorList[]=new Vector<Integer>[10];
6.使用?通配符可以引用其他各种参数化的类型。?通配符定义的变量主要用于引用,可以调用与参数无关
方法,不能调用与参数有关的方法。
7.通配符的扩展
限定通配符的上边界:Vector<?extends Number> x=new Vector<Integer>();
限定通配符的下边界:Vector<?super Integer> x=new Vector<>(Number);
8.自定义方法类型与应用:
注:只有引用类型才能作为泛型方法的实际参数。
8.1.交换数组中两个元素的位置
public static void main(String[]args)
{
swap(new String[]{"abc","cde","efg"},1,2);
}
//交换数组中两元素位置
public static <T> void swap(T[] a,int i,int j)//T为任意类型
{
T temp=a[i];
a[i]=a[j];
a[j]=temp;
}
9、除了在应用泛型时可以使用extends限定符,在定义泛型时也可以使用extends限定符。例如,Class.getAnonotation()方法的定义。并且可以用&来指定多个边界。
Eg:<V extends Serializable&cloneable> void method(){}.
普通方法、构造方法和静态方法都可以使用类型。
10.在泛型中可以同时有多个类型参数,在定义它们的尖括号中用逗号分,例如:
public static <K,V> V getValue(K key){return map.get(key)};
11.可以用类型变量表示异常,称为参数化异常,可以用于方法的throws列表中,但不能用于catch子句中。
Eg:
Private static <T extends Exception> sayHello()throws T
{
Try{
}catch(Exception e)
{
throw(T)e;
}
}
12.类型参数的类型推断:
12.1.当某个类型变量只在整个参数列表中的所有参数和返回值中的一处被应用,那么根据调用方法时该处的实际应用类型来确定。
Eg:swap(new String[3],3,4)------->static <E> void swap(E[] a,int i,int j)
12.2.当某个类型变量在整个参数列表中的所有参数和返回值中多处被应用了,如果调用方法时,这多处的实际应用类型都对应同一种类型来确定,这很容器根据感觉判断出来。
12.3当某个类型变量在整个参数类表中的所有参数和返回值被多处应用,如果调用方法时这多处的实际应用类型对应到不同的类型,且没有返回值,这时候取多个参数中的最大交集类型。
12.4.当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用,如果调用方法时这多处的实际应用类型对应到了不同的类型,且使用返回值,这时候优先考虑返回值的类型。
12.5.参数类型的类型推断具有传递性。
13.如果类的实例对象中的多处都要用到同一个泛型参数,即这些地方引用的泛型类型要保持同一个实际类型时,就要采用泛型类型的方式进行定义。也就是类级别的泛型。语法格式:
public class GenericDao<T>
{
private T field1;
public void save(T obj);
public T getByid(int id)
}
14.类级别的泛型是根据引用该类名时指定的类型信息来参数化类型变量,例如:
GenericDao<String> dao=null;
New GenericDao<String>();
15.在对泛型类型进行参数化时,类型参数的实例必须是引用类型,不能是基本类型。当一个变量被声明为泛型类型时,只能被实例变量和方法调用(还有内嵌类型),而不能被静态变量和静态方法调用。因为静态成员是被所有参数化的类所共享的,所以静态成员不应该有类级别的类型参数。
16.通过反射获得泛型的参数化类型
Vector<Date> v1=new Vector<Date>();//定义一个参数类型为Date的集合
Method method=Test.class.getMethod("applyVector", Vector.class);//获取成员方法applyVector
Type[] type= method.getGenericParameterTypes();//得到参数类型集合
ParameterizedType pt=(ParameterizedType)type[0];
System.out.println(pt.getActualTypeArguments()[0]);//得到Vector所用的参数类型
}
public static void applyVector(Vector<Date> v1){}