`

黑马程序员Java培训和Android培训Java技术三

 
阅读更多
黑马程序员
三十一
对javabean复杂内省操作
关键代码
BeanInfo beanInfo=Introspector.getBeanInfo(pt1.getClass());
PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors();
Object retVal=null;
for(PropertyDescriptor pd:pds)
{
if(pd.getName().equals(propertyName))
{
Method methodGetX=pd.getReadMethod();
retVal=methodGetX.invoke(pt1);
break;
}

}

三十二
Beanutils工具包
演示用eclipse如何加入jar包,先只是引入beanutils包,等程序运行出错后再引入logging包。
在前面内省例子的基础上,用BeanUtils类先get原来设置好的属性,再将其set为一个新值。
---get属性时返回的结果为字符串,set属性时可以接收任意类型的对象,通常使用字符串。
用PropertyUtils类先get原来设置好的属性,再将其set为一个新值。
---get属性时返回的结果为该属性本身的类型,set属性时只接受该属性本来的类型。
BeanUtils.getProperty();
BeanUtils.set();
BeanUtils支持对于属性的级联操作。java7中BeanUtils可以设置Map对象。
Map对象。JavaBean与Map可以相互转换,因为Map对象的的Key相当于属性。
PropertyUtils对于数据类型敏感。

三十三
Annotation注解:就是告诉编译器某些情况该如何处理。一个注解就是一个类。
存在于java.lang包中。Deprecated Override SuppressWarning

先通过@SuppressWarning的应用让大家直观地了解注解,然后引出@Deprecated @Override
总结:注解相当于一种标记,加了注解就等于给程序打上了某种标记,没加,则等于没有某种标记,以后,javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事。标记可以加在包中,类,字段,方法,方法的参数以及局部变量上。

三十四
isAnnotation()

自定义注解及其应用
定义一个最简单的注解:public @interface MyAnnotation{}
把它加在某个类上;@MyAnnotation public class AnnotationTest{}
用反射进行测试AnnotationTest的定义上是否有@MyAnnotation
根据发射测试的问题,引出@Retention元注解的讲解(即注解的注解),其三种取值:RetentionPolicy.SOURCE,RetentionPolicy.CLASS,RetentionPolicy.RUNTIME;分别对应:java源文件-->class文件-->内存中的字节码。

@target注解表明某一注解只能应用于某个特定的类型上。

三十五
为注解增加基本属性
什么是注解的属性
一个注解相当于一个胸牌,如果你胸前贴了胸牌,就是传智博客的学生,否则,就不是。如果还想区分出是传智博客哪个班的学生,这时候可以为胸牌增加一个属性来进行区分。加了属性的标记效果为:@MyAnnotation(color="red")
定义基本类型的属性和应用属性
在注解中增加String.color();
@MyAnnotation(color="red")
用反射的方式获得注解对应的实例对象后,再通过该对象调用属性对应的方法
MyAnnotation a=(MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
System.out.println(a.color());
可以认为上面这个@MyAnnotation是MyAnnotation类的一个实例对象
为属性指定缺省值:
String color() default"yellow";
value属性:
String value() default"zxx";
如果注解中有一个名称为value的属性,且你只想设置value属性(即其他属性都采用默认值或者你只有一个value属性),那么可以省略value=部分,例如:@MyAnnotation("ihm")。




为注解增加高级属性
数组类型的属性
---int[] arrayAttr() default {1,2,3}
---@MyAnnotation(arrayAttr={2,3,4})
---如果数组属性中只有一个元素,这时候属性值部分可以省略大括号。
枚举的属性
---EnumTest.TrafficLamp lamp();
---@MyAnnotation(lamp=EnumTest.TrafficLamp.GREEN)
注解类型的属性:
---MetaAnnotation annotationAttr() default @MetaAnnotation("xxxx");
---@MyAnnotation(annotionAttr=@MetaAnnotation("yyy"))
可以认为上面这个@MyAnnotation是MyAnnotion类的一个实例对象,t同样的道理,可以认为上面这个@MetaAnnotation是MetaAnnotation类的一个实例对象,调用代码如下:
MetaAnnotation ma=myAnnotion.annotationAttr();

注意:枚举和注解都是特殊的类,不能用new创建它们的实例对象,创建枚举的实例对象就是在其中增加元素。在程序中创建一个注解的实例对象,直接用@放上一个标记即可。
MetaAnnotation注解的定义:
public @interface MetaAnnotion{
   String value();
}
System.out.println(ma.value());
注解的详细语法可以通过看java语言规范了解,即java的Language Specification

我们可以尝试一下注释的Class类型的属性。

三十六
体验泛型
Jdk1.5以前的集合类中存在的问题
ArrayList collection=new ArrayList();
collection.add(1);
collection.add(1L);//存入一个长整型的数
collection.add("abc");
int i=(Interger)arrayList(1);//编译要强制类型转换且运行时出错!
Jdk 1.5的集合类希望你在定义集合时,明确表示你要向集合中装哪种类型的数据,无法加入指定类型以外的数据
ArrayList<Integer> collection2=new ArrayList<Integer>();
collection2.add(1);
/*collection2.add(1L);
collection2.add("abc");*///这两行代码编译时就报告了语法错误
int i2=collection2.get(0);//不需要再进行类型转换
泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去掉"类型"信息,使程序运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样。由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个类型集合中加入其他类型的数据,例如,用反射得到集合,再调用其add方法即可。

注意:泛型是jdk1.5的所有新特性中最难深入掌握的部分,不过,我们在实际应用中不能掌握的那么深入,掌握泛型中的一些最基本的内容就差不多了。没有使用泛型,只要是对象,不管是什么类型的对象,都可以存储进同一个集合中。使用泛型集合,可以将一个集合中的元素限定为一个特定类型,集合中只能存储同一个类型的对象,这样更安全;并且当从集合获取一个对象时,编译器也可以知道这个对象的类型,不需要对对象进行强制类型转换,这样更方便。
在jdk1.5中,你可以按原来的方式将各种不同类型的数据装到一个集合中,但编译器会报告unchecked警告。
泛型可以省去类型转换的繁琐。

三十七
了解泛型
ArrayList<E>类定义和ArrayList<Integer>类引用中涉及如下术语:
--整个称为ArrayList<E>泛型类型
--ArrayList<E>中的E称为类型变量或类型参数
--整个ArrayList<Integer>称为参数化的类型
--ArrayList<Integer>中的Integer称为类型参数的实例或实际类型参数
--ArrayList<Integer>中的<>念着typeof
--ArrayList称为原始类型
参数化类型与原始类型的兼容性:
--参数化类型可以引用一个原始类型的对象,编译报告警告,例如,Collection<String> c=new Vector();  //可不可以,不就是编译器一句话的事吗?
--原始类型可以引用一个参数化类型的对象,编译器报告,例如,Collection c=new Vector<String>();  //原来的方法接受一个集合参数,新的类型也要能传进去。
参数化类型不考虑类型参数的继承关系:
--Vector<String> v=new Vector<Object>(); //错误
--Vector<Object> v=new Vector<string>(); //也错误
在创建数组实例时,数组的元素不能使用参数化的类型,例如,下面语句有错误:
Vector<Integer> vector ist[]=new Vector<Integer>[10];
思考题:下面的代码会报错吗?
Vector v1=new Vector<String>();
Vector<Object> v=v1;不报错

泛型中的类型参数严格说明集合中装载的数据类型是什么和加入什么类型的数据,记住:Collection<String>和Collection<Object>是两个没有转换关系的参数化的类型。
假设Vector<String> v=new Vector<Object>;可以的话,那么以后从v中取出的对象当作String用,而v实际指向的对象中可以加入任意类型对象;假设Vector<Object> v=new Vector<String>();可以的话,那么以后可以向v中加入任意的类型对象,而v实际指向的集合中只能装String 类型的对象。

三十八
泛型中的?通配符 代表任意类型 带有通配符的定义的变量不能调用与参数类型有关的方法。
问题:
定义一个方法,该方法用于打印出任意参数化类型集合中的所有数据,该方法如何定义呢?
错误方式:
public static void printCollection(Collection<Object> cols)
{
    for(Object obj:cols)
    {
       System.out.println(obj);
     }
    /*cols.add("String");// 对
      cols=new HashSet<Data>();//会报告错误!*/

}

正确方式:
public static void printCollection(Collection<?> cols)
{
     for(Object obj: cols)
     {     System.out.println(obj);
     }
   //cols.add("String");错误,因为它不知自己未来匹配就一定是String
     cols.size();//没错,此方法与类型参数没有关系
     cols=new Hashset<Date>();
}
总结:
使用?通配符可以引用其他各种参数化的类型,?通配符定义的变量主要用作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。

/*Cols<Object>中的Object只是说明Cols<Object>实例对象中的方法接受的参数是Object
Cols<Object>是一种具体类型,new HashSet<Date>也是一种具体类型,两者没有兼容性问题。*/

Collection<?> a可以与任意参数化的类型匹配,但是到底匹配的是什么类型,只有以后才可以知道,所以,a=new ArrayList<Integer>和a=new ArrayList<String>都可以,但是a.add(new Date())或者a.add("abc")都不行。







通配符中的?通配符的扩展
限定通配符的上边界:
正确: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>();
提示:
限定通配符总是包括自己。

我理解的这个参数类型就是对于某种的更高层次抽象,赋值的原则为相关抽象可以引用相关的下一级具体。

三十九
泛型集合类的综合案例
能写出下面的代码即掌握了Java的泛型集合类:
HashMap<String.Integer> hm=new hashMap<String.Integer>();
hm.put("zxx",19);
hm.put("lis",18);

Set<Map.Entry<String.Integer>> mes=hm.entrySet();
for(Map.Entry<String.Integer> me: mes)
{
   System.out.println(me.getKey()+":"+me.getValue());
}


对在jsp页面中也经常要对Set或Map集合进行迭代:
<c:forEach items="${map}" var="entry">
${entry.key}:${entry.value}
</c:forEach>

四十
由C++的模板函数引入自定义泛型
如下函数的结构很相似,仅类型不同:
int add(int x,int y)
{
   return x+y;
}
float add(float x,float y)
{
  return x+y;
}
double add(double x,double y)
{
  return x+y;
}

C++用模板函数解决,只写了一个通用的方法,它可以适应各种类型,示意代码如下:
template<class T>
T add(T x,T y)
  {
     return(T)(x+y);
   }

定义泛型方法
Java的泛型方法没有C++模板函数功能强大,java中的如下代码无法通过编译:
<T> T add(T x,T y)
{
  return(T)(x+y);//return null
}

交换数组中的两个元素的位置的泛型方法语法定义如下:
static<E> void swap(E[] a,int i,int j)
{
   E t=a[i];
   a[i]=a[j];
   a[j]=t;
}

用于放置泛型的类型参数的尖括号应出现在方法的其他所有修饰符之后和在方法的返回类型之前,也就是紧邻返回值之前。按照惯例,参数类型通常用单个大写字母表示。

只有引用类型才能作为泛型方法的实际参数,swap(new int[3],3.5);语句会报告编译错误。

除了在应用泛型时可以使用extends限定符,在定义泛型时也可以使用extends限定符,例如,Class.getAnnotation()方法的定义。并且可以用&来指定多个边界,如<V extends Serializable& cloneable> void method(){}

普通方法,构造函数和静态方法中都可以使用泛型。编译器不允许创建类型变量的数组。

也可以用类型变量表示异常,称为参数化的异常,可以用于方法的throws列表中,但是不能用于catch子句中。

在泛型中可以同时有多个类型参数,在定义它们的尖括号中用逗号分,例如:
public static <K,V>V getValuale(K key){return map.get(key);}



用下面的代码说明对异常如何采用泛型
private static <T extends Exception> sayHello() throws T
{
  try{}
  catch(Exception e){
      throw(T) e;
    }
}

分享到:
评论

相关推荐

    黑马程序员java基础试题、笔记

    "黑马程序员java基础试题、笔记"这个压缩包资源为Java初学者和希望加入"黑马程序员"培训课程的学员提供了丰富的学习材料。这些资源包括面试问题合集、整理的资料、Android面试题、学员入学面试总结、面试技巧、必须...

    黑马程序员Android学习笔记

    总而言之,《黑马程序员Android学习笔记》是一份全面的学习资源,它不仅教授Android开发的基础,还覆盖了许多实际开发中可能遇到的问题和解决方案。通过深入学习和实践,你将能够熟练掌握Android应用开发,成为一名...

    黑马程序员_Java基础辅导班教程课件[第01期]第13天

    【Java基础辅导班教程...总之,"黑马程序员_Java基础辅导班教程课件[第01期]第13天"是一个全面覆盖Java基础的教程,结合课堂内容、视频、源码和图解,为学员提供了丰富的学习资源,助力他们稳步迈进Java开发的世界。

    黑马程序员Android视频教程

    ### 黑马程序员Android视频教程知识点解析 #### 一、Android基础概述 - **定义与特点**:Android是一种基于Linux内核(不包括GNU组件)的开源操作系统,主要用于移动设备。它由Google公司及其领导下的开放手机联盟...

    黑马程序员_从零开始征服Android之旅(第二季)源码和笔记(上)

    《黑马程序员_从零开始征服Android之旅(第二季)源码和笔记(上)》是一部针对初学者的全面Android开发教程,旨在帮助学员系统地掌握Android应用开发的基础知识和实战技巧。通过本教程的学习,你可以从理论出发,...

    黑马程序员_从零开始征服Android之旅(第一季)源码和笔记

    《黑马程序员_从零开始征服Android之旅(第一季)源码和笔记》是一份全面的Android开发学习资源,旨在帮助初学者系统地掌握Android开发技术,实现从理论到实践的跨越。这份资料涵盖了一系列关键知识点,包括但不限于...

    黑马程序员入学测试题

    【标题】:“黑马程序员入学测试题”是一份用于评估编程基础和理解能力的测试集,主要针对准备加入黑马程序员培训课程的学生。这份测试题旨在帮助新手程序员检验自己的知识水平,以便更好地适应学习环境。 【描述】...

    安卓黑马程序员课表

    ### 安卓黑马程序员课程知识点概览 #### 1. XML编程 ...以上为“安卓黑马程序员课表”中涉及的主要知识点概览,通过系统的学习与实践,学员能够建立起坚实的IT技术基础,并具备实际项目开发的能力。

    黑马程序员毕向东java基础课堂完整版文档

    《黑马程序员毕向东Java基础课堂完整版文档》是一份全面且深入的Java学习资源,由知名教育机构黑马程序员的讲师毕向东倾力打造。这份资料涵盖了从Java编程基础到高级特性的全过程,旨在帮助初学者系统地掌握Java编程...

    黑马程序员最新一期高清教学视频

    根据提供的文件信息,这里将对“黑马程序员最新一期高清教学视频”进行详细的解析与扩展,以便更好地理解其中可能涵盖的知识点和技术内容。 ### 黑马程序员教学视频概述 #### 标题解读:“黑马程序员最新一期高清...

    黑马程序员 从零开始征服Android之旅(第一季)源码和笔记 下

    在本资源包“黑马程序员 从零开始征服Android之旅(第一季)源码和笔记 下”中,我们聚焦于Android应用程序开发的基础与实践。通过学习,你可以系统地掌握Android开发的核心概念,逐步成长为一名合格的Android开发者...

    黑马程序员安卓Android52期培训课

    2015/3/4 星期三 android案例与项目—手机安全卫士练习 2015/3/5 星期四 2015/3/6 星期五 android案例与项目—手机安全卫士 2015/3/7 星期六 android案例与项目—手机安全卫士 2015/3/8 星期日 android案例与项目—...

    黑马程序员《Java自学宝典》源代码

    Java自学宝典是针对初学者和有一定基础的学习者设计的一套完整的Java学习资源,由知名的教育机构黑马程序员出品。这份源代码压缩包包含了书中各个章节的实例代码,旨在帮助学习者深入理解Java编程语言的核心概念和...

    黑马程序员_2小时教你写一个android程序[第05天]课件源码

    在本课程中,“黑马程序员”将引导我们逐步学习如何在短短两小时内编写一个Android应用程序。这个教程特别关注的是第5天的内容,主要涉及到天气预报应用的开发,包括数据获取、数据显示以及网络图片的查看功能。下面...

    黑马程序员_毕向东最新经典Java基础视频

    根据提供的文件信息,我们可以推断出这是一套由知名IT教育机构“黑马程序员”出品、由讲师毕向东主讲的Java基础教学视频。由于实际视频内容无法直接获取,本篇将依据标题、描述以及部分标签内容,综合分析并展开相关...

    黑马74期 安全卫士android源码

    【标题】"黑马74期 安全卫士android源码"揭示了这是一份针对Android平台的安全卫士应用的源代码,源自知名的黑马程序员培训课程的第74期。这个安全卫士软件旨在保护用户的Android设备,提供了一系列功能来确保设备的...

    传智播客、黑马程序员 红孩子电子商城客户端和服务端源代码及开发文档

    红孩子电子商城项目,由知名教育机构传智播客和黑马程序员联合推出,旨在为学员提供一套完整的电商系统开发实践案例。该项目涵盖了客户端和服务端的源代码,以及详尽的开发文档,是学习和理解电商系统开发的宝贵资料...

    黑马程序员_Java基础辅导班教程课件[第01期]第10天

    在"黑马程序员_Java基础辅导班教程课件[第01期]第10天"中,我们聚焦于Java编程语言的基础知识,这是一门面向初学者的课程,旨在帮助学员快速掌握Java的核心概念。通过这个阶段的学习,学员将能够理解并运用Java的...

    黑马程序员_2小时教你写一个安卓程序[第03天]课件源码

    在本课程中,“黑马程序员”将引导我们逐步学习如何在短短两小时内编写一个基础的安卓应用程序。这是一门针对初学者的安卓编程教程,重点在于快速掌握安卓开发的基础概念和实践技能。第03天的课件源码包含了构建安卓...

Global site tag (gtag.js) - Google Analytics