---------------------- android培训、java培训、期待与您交流! ----------------------
10.java中的内省
java中的内省又叫JavaBean是一种特殊的类,它其中的方法名称符合某种约定的规则,例如:
public class person {
private int age;
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
}
符合上述中的getAge()和setAge()的方法即是javabean类。
总之,一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java
类内部的成员变量。一个符合JavaBean特点的类可以当作普通类一样进行使用,但把它当JavaBean用
肯定需要带来一些额外的好处,我们才会去了解和应用JavaBean!Java EE开发中,经常要使用到JavaBean。很多环境就要求按JavaBean方式进行操作,别人都这么用和要求这么做,那你就没什么挑选的余地!
其中的示例代码如下:
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
ReflectPoint rp = new ReflectPoint(3, 5);
String getx = "x";
//"x"-->"X"-->"getX"-->MethodGetX-->普通方法这样写会很麻烦
PropertyDescriptor pd = new PropertyDescriptor(getx, rp.getClass());//PropertyDescriptor是属性描述符的类
Method method = pd.getReadMethod();
Object retval = method.invoke(rp);
System.out.println(retval);
}
总结:
通过PropertyDescriptor类,把要变成JavaBean的那个类和要操作的参数传进去,
然后再通过PropertyDescriptor类的set或get方法获取对象中操作那个变量的方法,
然后通过invoke让指定对象去操作这个方法。
对JavaBean进行内省操作
1. 通过 PropertyDescriptor 类操作那个JavaBean类
2. 采用遍历BeanInfo的所有属性方式来查找和设置某个RefectPoint对象的X属性,在程序
中把一个类当作JavaBean来看,就是调用IntroSpecto.getBeanInfo方法,
得到的BeanInfo对象封装了吧这个类当作JavaBean看的结果信息。
Beanutils与PropertiesUtils的区别:
部分代码:
BeanUtils.setProperty(pt1, "birthday.time", "111");
System.out.println(BeanUtils.getProperty(pt1, "birthday.time"));
PropertyUtils.setProperty(pt1, "x", 9);
System.out.println(PropertyUtils.getProperty(pt1, "x").getClass().getName());
BeanUtils是以字符串的形式对javabean进行操作,
而PropertiesUtils是以属性本身的类型进行操作。
Beanutils可以与map相互转换
11、java注解
注解,顾名思义,注解,就是对某一事物进行添加注释说明,会存放一些信息,这些信息可能对以后某个时段来说是很有用处的。
Java注解又叫java标注,java提供了一套机制,使得我们可以对方法、类、参数、包、域以及变量等添加标准(即附上某些信息)。且在以后某个时段通过反射将标注的信息提取出来以供使用。
Java标注
Java从1.5版本以后默认内置三个标注:
@Override 表示当前方法是覆盖父类的方法。
@Deprecated 表示当前元素已过时。
@SuppressWarnings 表示关闭一些不当的编译器警告信息,就是不让你警告了你别管了。
但是,仅仅这三个标注是不能满足我们开发时一些需求的。所以java允许我们自定义注解来使用。
自定义步骤大致分为两步:
1,通过@interface关键字(注意,不是interface,是@interace)声明注解名称,以及注解的成员属性或者叫做注解的参数。
2,使用java内置的四个元注解对这个自定义标注的功能和范围进行一些限制
问题来了,什么是元注解?
元注解,就是定义注解的注解,也就是说这些元注解是的作用就是专门用来约束其它注解的注解。
12.泛型
了解泛型
ArrayList<E>类定义和ArrayList<Integer>类引用中涉及的术语:
1、 整个ArrayList<E>称为泛型类型
2、ArrayList<E>中E称为类型变量或类型参数
3、整个ArrayList<Integer>称为参数化的类型
4、ArrayList<Integer>中的Integer叫类型参数的实例或实际类型参数
5、ArrayList<Integer>中的<>念typeof
6、ArrayList称为原始类型
参数化类型与原始类型的兼容性-编译警告 Collection<String> = new Vector(); Collection = new Vector<String >();
参数化类型不考虑类型参数的继承关系 Vector<String> v = new Vector<Object>(); //错!
Vector<Object> v = new Vector<String>();//错!
在创建数组实例时,数组的元素不能使用参数化的类型 Vector<Integer> v[] = new Vector<Integer>[10];
Vector v1 = new Vector<Integer>(); Vector<Object> v = v1; //编译可以通过!编译器只会按行解释
注意:Vector<String> v1 = new Vector<String>();
Vector<Integer> v2 = new Vector<Integer>();
当这两个泛型对象编译完了以后,他们的类型是一样的
System.out.println(v1.equals()v2);//返回true
泛型的?通配符及扩展
<?>可以引用各种参数化的类型,可以调用与参数无关的方法,不能调用与参数有关的方法
限定通配符的上边界 正确:Vector<? extends Number> v=new Vector<Integer>(); 错误:Vector<? extends Number> v=new Vector<String>();
限定通配符的下边界 正确:Vector<? Super Integer> v=new Vector<Number>(); 错误:Vector<? extends Integer > v=new Vector<Byte>();
通配符包括自己
public static void printCollection(Collection<?> cols)
{
for(Object obj:cols)
{
System.out.println(obj);
}
//cols.add("string");//错误,因为它不知自己未来匹配就一定是String
cols.size();//没错,此方法与类型参数没有关系
cols = new HashSet<Date>();
}
泛型扩展
限定通配符的上边界:
正确:Vector<? extends Number> x = new Vector<Integer>();
错误:Vector<? extends Number> x = new Vector<String>();
限定通配符的下边界:
正确:Vector<? super Integer> x = new Vector<Number>();
错误:Vector<? super Integer> x = new Vector<Byte>();
上限:?extends E:可以接收E类型或者E的子类型对象。
下限:?super E:可以接收E类型或者E的父类型对象。
上限什么时候用:往集合中添加元素时,既可以添加E类型对象,又可以添加E的子类型对象。
为什么?因为取的时候,E类型既可以接收E类对象,又可以接收E的子类型对象。
下限什么时候用:当从集合中获取元素进行操作的时候,可以用当前元素的类型接收,也可以用当前元
素的父类型接收。
通过综合案例来演示泛型的特点
需求:把map集合的数据转成由set的方法输出:
Set keySet();
Set entrySet();//取的是键和值的映射关系。
public static void main(String[] args) {
// TODO Auto-generated method stub
HashMap<String,Integer> maps = new HashMap<String,Integer>();
maps.put("abc", 1);
maps.put("xyz", 1);
maps.put("123", 1);
Set<Map.Entry<String, Integer>> entrySet = maps.entrySet();
for(Map.Entry<String, Integer> map : entrySet){
System.out.println(map.getKey()+":"+map.getValue());
}
}
泛型类:将泛型定义在类上。
class Tool<Q>
{
private Q obj;
public void setObject(Q obj)
{
this.obj = obj;
}
public Q getObject()
{
return obj;
}
}
用于放置泛型的类型参数的尖括号应出现在方法的其他所有修饰符之后和在方法的返回类型之前,
也就是紧邻返回值之前。按照惯例,类型参数通常用单个大写字母表示。
13、类加载器
自定义类加载器:
1,引导类加载器(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的,并不
继承自 java.lang.ClassLoader。运行JRE/lib/rt.jar里面的类
2,扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一
个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。这里面的JRE/lib/ext/ *.jar
3,系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般
来说,Java 应用的类都是由它来完成加载的。可以通过
ClassLoader.getSystemClassLoader() 来获取它。
类加载器的委托机制
当java中要加载一个类时,每个类加载器加载类时,先委托给其上级类加载器。就是父类先加载最后才轮
到发起的的类加载器。 BootStrap--->ExtClassLoader--->AppClassLoader
自定义类加载器步骤:
1.编写一个对文件内容进行简单加密的程序。
2.编写了一个自己的类装载器,可实现对加密过的类进行装载和解密。
3.编写一个程序调用类加载器加载类,在源程序中不能用该类名定义引用变量,因为编译器无法识别这个
类。程序中可以除了使用ClassLoader.load方法之外,还可以使用设置线程的上下文类加载器或者系统
类加载器,然后再使用Class.forName。
---------------------- android培训、java培训、期待与您交流! ----------------------