枚举:定义
枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。
枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。
枚举元素必须位于枚举体中的最开始部分,枚举元素列表的后要有分号与其他成员分隔。把枚举中的成员方法或变量等放在枚举元素的前面,编译器报告错误。
带构造方法的枚举
Ø 构造方法必须定义成私有的
Ø 如果有多个构造方法,该如何选择哪个构造方法?
Ø 枚举元素MON和MON()的效果一样,都是调用默认的构造方法。
带方法的枚举
Ø 定义枚举TrafficLamp
Ø 实现普通的next方法
Ø 实现抽象的next方法:每个元素分别是由枚举类的子类来生成的实例对象,这些子类采用类似内部类的方式进行定义。
Ø 增加上表示时间的构造方法
枚举只有一个成员时,就可以作为一种单例的实现方式。
public enum WeekDay{
SUN,MON,TUE,WED,THI,FRI(),SAT(3); //此处传递一个参数就会调用带参构造方法也可以直
//接一个括号来调用第二个构造方法
private weeDay(){}; //写构造方法必须是私有的 ,初始化时调用无参数的。
private weekDay(int day){}
}
反射就是把Java类中的各种成分映射成相应的java类
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
1、得到某个类所有的构造方法:
例子:Constructor []constructors= Class.forName("java.lang.String").getConstructors();
2、得到某个类一个的构造方法:
Constructor constructor= Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);
Class.newInstance()方法:
String obj =(String)Class.forName("java.lang.String").newInstance();
该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
该方法内部的具体代码是怎样写的呢?用到了缓存机制来保存默认构造方法的实例对象。
创建实例对象:
通常方式:String str =new String(new StringBuffer("abc"));
反射方式: Stringstr = (String)constructor.newInstance(new StringBuffer("abc"));
Field类代表某个类中的一个成员变量
演示用eclipse自动生成Java类的构造方法
问题:得到的Field对象是对应到类上面的成员变量,还是对应到对象上的成员变量?类只有一个,而该类的实例对象有多个,如果是与对象关联,关联的是哪个对象呢?所以字段fieldX代表的是x的定义,而不是具体的x变量。
示例代码:
ReflectPointpoint = new ReflectPoint(1,7);
Fieldy =Class.forName("cn.itcast.corejava.ReflectPoint").getField("y");
System.out.println(y.get(point));
//Fieldx = Class.forName("cn.itcast.corejava.ReflectPoint").getField("x");
Fieldx = Class.forName("cn.itcast.corejava.ReflectPoint").getDeclaredField("x");
x.setAccessible(true); //暴力反射
System.out.println(x.get(point));
Method类代表某个类中的一个成员方法
Method charAt = Class.forName("java.lang.String").getMethod("charAt",int.class);
调用方法
通常方式:System.out.println(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工具类用于完成对数组的反射操作。
Arrays.deepToString()方法不能处理int[],但能处理String[]
反射可以实现框架功能
重写Overriding和重载Overloading
方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。