黑马程序员_基础加强02

来源:互联网 发布:linux snmp 无法启动 编辑:程序博客网 时间:2024/05/17 22:07


----------------------Android培训、Java培训、java学习型技术博客、期待与您交流! ----------------------


哈希值:
1、通常来说,一个类的两个实例对象用equals()方法比较的结果相等时,他们的
 哈希值也必须相等,但是反之则不成立。
2、当一个对象被存储进HashSet集合中以后,就不能在修改这个对象中那些参与计算哈希值的字段,
 否则,对象修改后的哈希值与最初存储进HashSet集合中的哈希值就不相同了,在这种情况下,
 即使在contains方法使用对象的当前引用作为参数去HashSet集合中检索对象,也将返回false,
 这也会导致无法从HashSet集合中单独删除当前对象,从而造成内存泄露。

import java.util.*;class HashCodeDemo{public static void main(String[] args) {HashSet<TextClass> hs = new HashSet<TextClass>();TextClass tc1 = new TextClass(2,3);TextClass tc2 = new TextClass(3,5);hs.add(tc1);hs.add(tc2);tc1.set(2,4);System.out.println(hs.contains(tc1));//falseSystem.out.println(hs.remove(tc1));//false}}class TextClass{private int x;private int y;TextClass(int x, int y){this.x = x;this.y = y;}public void set(int x, int y){this.x = x;this.y = y;}public int hashCode(){return x+y;}public boolean equals(Object obj){if(!(obj instanceof TextClass))throw new RuntimeException("类型错误");TextClass tc = (TextClass)obj;return this.x==tc.x && this.y==tc.y;}}

内省(IntroSpector):主要用于对JavaBean进行操作。

JavaBean是一种特殊的java类,主要用于传递数据信息。
这种java类方法主要用于访问私有的字段,且方法名符合某种命名规则。

PropertyDescriptor 描述 Java Bean 通过一对存储器方法导出的一个属性。
PropertyDescriptor(String propertyName, Class<?> beanClass)
          通过调用 getFoo 和 setFoo 存取方法,为符合标准 Java 约定的属性构造一个 PropertyDescriptor。
Method getReadMethod()
          获得应该用于读取属性值的方法。
Method getWriteMethod()
          获得应该用于写入属性值的方法。

import java.beans.PropertyDescriptor;import java.lang.reflect.*;class IntroSpectorDemo{public static void main(String[] args) throws Exception{Person p = new Person("lxh",24);String propertyName1 = "name";PropertyDescriptor pd1 = new PropertyDescriptor(propertyName1,p.getClass());Method methodGet = pd1.getReadMethod();Object retVal = methodGet.invoke(p);System.out.println(retVal);String propertyName2 = "age";PropertyDescriptor pd2 = new PropertyDescriptor(propertyName2,p.getClass());Method methodSet = pd2.getWriteMethod();methodSet.invoke(p,23);System.out.println(p.getAge());}}class Person{private String name;private int age;Person(String name, int age){this.name = name;this.age = age;}public void setAge(int age){this.age = age;}public int getAge(){return age;}public void setName(String name){this.name = name;}public String getName(){return name;}}


注解:相当于一种标记,在程序中加入注解就等于为程序打上了一个标记。
 加了标记,javac编译器,开发工具和其他程序就可以通过反射来了解类及各种元素上有无标记,从而去做相应的事。
 标记可以加在包、类、方法、方法的参数以及局部变量上。
例如:java.lang包下的三个基本注释
@Deprecated、@Override、@SuppressWarnings

注解类:格式
@interface A
{
}

枚举 RetentionPolicy
枚举常量摘要 :
CLASS 编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。
RUNTIME 编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。
SOURCE 编译器要丢弃的注释。

@Retention:指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS

枚举 ElementType
枚举常量摘要
ANNOTATION_TYPE 注释类型声明
CONSTRUCTOR 构造方法声明
FIELD 字段声明(包括枚举常量)
LOCAL_VARIABLE 局部变量声明
METHOD 方法声明
PACKAGE 包声明
PARAMETER 参数声明
TYPE 类、接口(包括注释类型)或枚举声明

@Target:指示注释类型所适用的程序元素的种类。如果注释类型声明中不存在 Target 元注释,则声明的类型可以用在任一程序元素上。

import java.lang.annotation.*;import java.lang.reflect.*;@ItcastAnnotation(value="abc")class AnnotationDemo{public static void main(String[] args) {//判断在运行时AnnotationDemo内是否还有注释@ItcastAnnotation。if(AnnotationDemo.class.isAnnotationPresent(ItcastAnnotation.class)){//通过ItcastAnnotation的映射获取其对象ItcastAnnotation itcastAnno =(ItcastAnnotation)AnnotationDemo.class.getAnnotation(ItcastAnnotation.class);System.out.println(itcastAnno.value());}}}//自定义注释,设置其存在时间和位置@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE, ElementType.METHOD})@interface ItcastAnnotation{//设置属性,color为固定值String color() default "blue";String value();}


泛型:
泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序的非法输入。
为了使运行效率不受影响,在编译生成的字节码会去掉泛型的类型信息,所以只要跳过编译器就可以向某个泛型的集合中加入其它类型的元素。
比如使用反射获得集合,在调用add方法即可。

泛型中的术语:
例:ArrayList<E>类定义和ArrayList<String>类引用中涉及到的术语
整个成为ArrayList<E>泛型类
ArrayList<E>中的E称为类型变量或类型参数
整个ArrayList<String>称为参数化的类型
ArrayList<String>中的String称为类型参数的实例或实际类型参数
ArrayList<String>中的<>念作type of
ArrayList称为原始类型

参数化类型与原始类型的兼容性:
Collection<String> coll = new Vector()
 参数化类型可以引用一个原始类型的对象,编译会报告警告
Collection coll = new Vector<String>()
 原始类型可以引用一个参数化类型的对象,编译时会报告警告。
注:参数化类型不考虑类型参数的继承关系,即:
Vector<String> v = new Vector<Object>();//错误
Vector<Object> v = new Vector<String>();//错误
注;在创建数组实例时,数组元素不能使用参数化的类型。

自定义泛型:
普通方法、构造方法和静态方法中都可以使用泛型。
也可以用类型变量表示异常,称为参数化的异常。可以用于方法的throws列表中,但不能用于catch子语句中。
注意事项:
1、只有引用类型才能作为泛型方法的实际参数。
2、用于放置泛型参数的尖括号位于返回值类型前,且紧挨着返回值类型。
3、除了在应用泛型是可以使用extends限定符外,在定义泛型时也可以使用。
4、在泛型中可以同时有多个类型参数,在定义它们的尖括号中用逗号分开

类型参数的类型推断:
1、当某个类型变量只在整个参数列表中的所有参数和返回值中的一处被应用,
那么根据调用方法时该处的实际应用类型来确定,即直接根据调用方法时传递的参数类型或返回值来决定。
2、当某一类型变量在整个参数列表中所有参数和返回值中的多处被应用,
如果调用方法时这多处的实际应用类型都对应同一种类型来确定。
3、当某一类型变量在整个参数列表中所有参数和返回值中的多处被应用,
如果调用方法时这多处的实际应用类型都对应到不同种类型,且没有使用返回值,这是取多个参数的最大交集。
4、当某一类型变量在整个参数列表中所有参数和返回值中的多处被应用,
如果调用方法时这多处的实际应用类型都对应到不同种类型,且使用返回值,这是优先考虑返回值类型。

import java.util.*;import java.lang.reflect.*;class GenericDemo{public static void main(String[] args) throws Exception{ArrayList<String> alString = new ArrayList<String>();ArrayList<Integer> alInteger = new ArrayList<Integer>();alString.add("abc");alString.add("cba");System.out.println(alString);//[abc, cba]System.out.println(alString.getClass()==alInteger.getClass());//truealString.getClass().getMethod("add",Object.class).invoke(alString,3);System.out.println(alString);//[abc, cba, 3] }}


----------------------Android培训、Java培训、java学习型技术博客、期待与您交流! ----------------------



0 0
原创粉丝点击