package qian.com;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
interface Generator<T>{
public T next();
}
enum Year{ SPRING,SUMMER,AUTUMN,WINTER}
enum Direction implements Generator<Direction>{
EAST("i am east"),
WEST("i am west"),
NORTH("i am north"),
//这个分号不能省略;
private String descript;
//因为我们只能在Year这个枚举类的内部创建其对象,
//所以将其声明为私有的;
private Direction(String descript){
this.descript = descript;
}
public String getDescript(){
return descript;
}
//和别的类一样,我们也可以覆盖toString()方法
public String toString(){
String name = this.name();
return name.charAt(0)+name.substring(1).toLowerCase();
}
@Override
public Direction next() {
return Direction.values()[new Random().nextInt(Direction.values().length)];
}
}
public class EnumTest {
public static void method1(){
/*展示enum定义的类中都有哪些方法,发现其除了
*有object中的方法外
* 还有如下方法;
*
* */
for(Year y:Year.values()){
System.out.println("----Enum method()----");
System.out.println("y.compareTo(Year.WINTER): "+y.compareTo(Year.WINTER));
System.out.println("y.equals(Year.WINTER): "+y.equals(Year.WINTER));
System.out.println("y.hashCode(): "+y.hashCode());
System.out.println("y.name(): "+y.name());
System.out.println("y.ordinal(): "+y.ordinal());
System.out.println("y.toString(): "+y.toString());
System.out.println("y.getClass(): "+y.getClass());
System.out.println("----Year method()----");
System.out.println("y.valueOf(WINTER): "+y.valueOf("WINTER"));
System.out.println("y.values().length: "+y.values().length);
System.out.println("---------------------");
}
}
public static void method2(){
for(Direction d:Direction.values()){
System.out.println(d.toString()+" : "+d.getDescript());
}
}
public static void method3(){
//方法三 来展示枚举类的 switch方法;
//一般来说switch方法中只能使用整数值,而枚举实例
//天生就具备整数值的次序;并且我们也可以
//通过ordinal()方法来获取其次序,
Year[] ys = Year.values();
Random rand = new Random();
String randName = ys[rand.nextInt(ys.length)].name();
switch(randName){
case "SPRING" :{
System.out.println("randName is spring");
break;
}
case "SUMMER" :{
System.out.println("randName is summer");
break;
}
case "AUTUMN" :{
System.out.println("randName is autumn");
break;
}
case "WINTER" :{
System.out.println("randName is winter");
break;
}
default:{
System.out.println(" it is wrong");
}
}
}
public static void method4(){
//详细讲解values()方法;
//我们知道编译器为我们创建的enum类都自动继承与Enum类
//但是我们发现Enum类中并没有values方法;
class Reflection{
public Set<String> analyse(Class<?> enumClass){
/*for(Type t:enumClass.getGenericInterfaces()){
System.out.println(t);
}*/
Set<String> methods = new TreeSet<String>();
for(Method m:enumClass.getMethods()){
methods.add(m.getName());
}
System.out.println(enumClass.getSimpleName()+":");
System.out.println(methods);
return methods;
}
}
Set<String> yearMethods = new Reflection().analyse(Year.class);
Set<String> enumMethods = new Reflection().analyse(Enum.class);
System.out.println(yearMethods.containsAll(enumMethods));
/*从输出结果可以看出,
1,Enum类中没有values()方法;
2.Enum类中的valueOf()需要两个参数而Year类中只需要一个参数
可以见得是编译器在编译时候给你 Year类添加了这两个方法,
那么就会存在一个问题,就是enum修饰的枚举类再向上转型
成Enum时,其中的values()方法就会没有了,这怎么解决:
用到反射Class类中的getEnumConstants()方法可以得到Year
中的所有实例;*/
Enum[] es = Year.SPRING.getClass().getEnumConstants();
for(Enum ee:es)
System.out.println(ee);
}
public static void method5(){
/*我们知道java是单继承的 既然每一个enum都继承与Enum,
那么它就不能继承别的类了怎么办;
那就实现多个接口呗
比如我们让上面的Direction枚举类实现生成器接口;*/
//1.必须要拿到一个enum实例,才可以调用其内部的方法;
Direction dir = Direction.EAST;
for(int i=0;i<5;i++)
System.out.print(dir.next().name()+" ");
System.out.println();
for(int i=0;i<5;i++)
System.out.print(RandEnumTools.random(Year.class)+" ");
}
public static void main(String [] args) {
//method1();
method5();
}
}
//插曲:由方法5我们可以看到,我们经常需要随机生成一个枚举实例:
//那么直接用反射做个工具类包:
class RandEnumTools{
private static Random rand = new Random();
public static <T extends Enum<T>> T random(Class<T> ec){
return random(ec.getEnumConstants());
}
public static <T> T random(T[] values){
return values[rand.nextInt(values.length)];
}
}