枚举
枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。枚举可以让编译器在编译时就可以控制源程序中填入的非法值,普通变量的方式在开发阶段无法实现这一目标。
枚举功能:1 私有的构造方法
2 每个元素分别用一个公有的静态成员变量表示
3 可以有若干公有方法或抽象方法
定义枚举的关键字 enum
Public enum WeekDay{
MON,TUE,WED,THI,FRI,SAT,SUN
private WeekDay(){}
};
定义枚举 可以自动实现toString方法
静态方法:valueOf(String s); 把一个字符串编程对应枚举元素。
values();把枚举里的每一个元素装进一个数组。
枚举类里的所有方法必须位于元素之后。
枚举的构造方法必须是私有的。
在元素后加上一个括号 就表示创建这个元素事项这个实例对象的时候使用的是哪个构造方法。
枚举只有一个成员时,就可以作为一种单例的实现方式。
Class类 (反射的基石)
Java类用于描述一类事物的共性,该类事物有什么属性,没有什么属性,至于这个属性的值是什么,则是由这个类的实例对象来确定的,不同的实例对象有不同的属性值。
Java程序中的各个java类属于同一类事物,描述这类事物的Java类名就是Class,要注意与小写class关键字的区别,Class类描述了类的名字,类的访问属性,类所属于的包名,字段名称的列别,方法名称的列表,等等。
得到各个字节码对应的实例对象(Class类型)
1 类名.class 例如,System.class
2 对象.getClass(),例如,new Date.getClass();
3 Class.forName(“类名”),例如, Class.forName(“java.util.Date”);
九个预定义的Class实例对象:
8个基本类型 void ;
int.class = Integer.TYPE ; TYPE代表包装类型所包装的基本类型的字节码
数组类型的Class实例对象
Class.isArray()
总之,只要是在源程序中出现的类型,都有各自的Class实例对象,例如,int[] , void…
isPrimitive();查看是否是基本类型;
反射
反射就是就是把java类中的各种成分映射成相应的java类。例如,一个java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相对应类的实例对象来表示,他们是Filed,Method,Contructor,Package等等。
Constructor类代表某个类的构造方法
得到某个类的所有构造方法:
Constructor[] constructor = Class.forName(“java.lang.String”).getConstructors();
得到某一个构造方法:
Constructor constructor=Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);
创建实例对象:
通常方式:String str = new String(new StringBuffer(“abc”));
反射方式:String str = (String)constructor.newInstance(new StringBuffer(“abc”));
调用获得的方法时要用到上面相同类型的实例对象
Class.newInstance()方法:
例子 String obj =(String) Class.forName(“java.lang.String”).newInstance();
该方法内部先得到默认的构造方法,然后用构造方法创建实例对象
该方法内部的具体代码用到了缓存机制来保存默认的构造方法和实例对象
Filed类代表某个类的一个成员变量;
Field field =XXX.forName().getField(“变量名”);不能得到私有的成员变量
Filed不是对象上的变量,而是类上,要用他去取某个对象上的值
field.get(XXX);得到XXX对象上的值
Field field =XXX.forName().getDeclaredField(“变量名”);得到所有的声明的成员变量,不考虑私有
Field.setAccessible(true);先设置为可疑访问 才能得到私有属性值(暴力反射);
field.get(XXX);
字节码的比较用==
Method类代表某个类中的一个成员方法
得到类中的某一个方法:
例子:Method charAt = Class.forName(“java.lang.String”).getMethod(“charAt”,int.class);
调用方法:System.out.prinln(str.charAt(1));
反射方式:System.out.println(charAt.invoke(str,1));
如果传递给Method对象的invoke()方法的第一个参数为null,说明该Method对象对应的是一个静态方法!
数组的反射
具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。
代表数组的Class实例对象的getSuperclass()方法返回回的父类为Object类对应的Class.
基本类型的一维数组可以被当做Object类型使用,不能当做Object[]类型使用;为基本类型的一维数组,既可以当做Object类型使用,又可以当做Object[]类型使用。
Arrays.asList()方法处理int[]和String[]时的差异类。
Array工具类用于完成对数组的反射操作。
HashCode 方法
如果想要找到一个集合中是否包含某个对象,大概的程序怎么写呢?你通常是逐一取出每个元素要与查找对象进行比较,当发现某个元素与要查找的对象进行equals方法比较的结果相等时,则停止继续查找并返回肯定的信息,否则,返回否定的信息。如果一个集合中有很多个元素,譬如一万个元素,并且没有包含要查找的对象时,则意味着你的程序要从该集合中取出一万个元素进行逐一比较才能得到结论。
有人发明了一种哈希算法来提高从集合中查找元素的效率,这种方式将集合分成若干个存储区域,每个对象可以计算出一个哈希码,可以将哈希码分组,这种方式将集合分成若干个存储区域,,根据一个对象的哈希码就可以确定该对象存在哪个区域。
HashSet就是采用哈希算法存取对象的集合,它内部采用对某个数字N进行取余的方式对哈希码进行分组和划分对象的存储区域,Object类中定义了一个hashCode()方法来返回每个Java对象的哈希码,当从HashSet集合中查找某个对象时,Java系统首先调用对象的HashCode()方法回的该对轩昂的哈希码,然后根据哈希码找到相应的存储区域,最后取出该存储区域内的每个元素与对象进行 equals方法比较,这样不用遍历集合中的所有元素就可以得到结论。