Java泛型和枚举

泛型:

泛型推荐文章:
http://t.csdn.cn/OeI1a

http://t.csdn.cn/hhbCs

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。

泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

List list= new ArrayList();

list.add(new Student());//只能存储Student对象和它的子类对象了。

list.add("adb");//使用泛型之后就会编译报错。 

注意:

1, 泛型这种机制,只在程序编译阶段起作用,只是给编译器参考的。(运行阶段泛型没用!)

2,在给泛型指定具体类型后,可以传入该类型或者其子类类型

3,泛型的本质就是"参数化类型"。一提到参数,最熟悉的就是定义方法的时候需要形参,调用方法的时候,需要传递实参。那"参数化类型"就是将原来具体的类型参数化

4,(自定义泛型)泛型的三种使用方式:泛型类泛型方法泛型接口

 泛型类:

  • 泛型类概述:把泛型定义在类上
  • 注意事项:泛型类型必须是引用类型(非基本数据类型)
  • 定义格式

public class 类名 <泛型类型1,...> {
   
}

泛型方法

  • 泛型方法概述:把泛型定义在方法上
  • 定义格式

public <泛型类型> 返回类型 方法名(泛型类型 变量名) {
    
}

注意要点:

1,方法声明中定义的形参只能在该方法里使用,而接口、类声明中定义的类型形参则可以在整个接口、类中使用。当调用fun()方法时,根据传入的实际对象,编译器就会判断出类型形参T所代表的实际类型。

2,静态方法中不能使用类的泛型

3,泛型类的类型是在创建对象时确定的

4,如果创建对象时没有指定类型,默认为Object

5,使用泛型的数组,不能初始化

class Demo{

public T fun(T t){// 可以接收任意类型的数据

return t ; // 直接把参数返回

泛型接口

  • 泛型接口概述:把泛型定义在接口
  • 定义格式:

public interface 接口名<泛型类型> {
    
}

/**
 * 泛型接口的定义格式:        修饰符  interface 接口名<数据类型> {}
 */
public interface Inter {
    public abstract void show(T t) ;
}

/**
 * 子类是泛型类
 */
public class InterImpl implements Inter {
    @Override
    public void show(E t) {
        System.out.println(t);
    }
}
Inter inter = new InterImpl() ;
inter.show("hello") ;

注意:只有在定义方法,类和接口的时候定义了泛型,才能在调用的时候加上泛型

看下面的自定义泛型的代码就可以理解了。

注意:

1,自定义泛型的时候,<>尖括号中的是一个标识符,随便写。

        Java源代码中常出现的是,

        E是Element单词的首字母

        T是Type单词的首字母

2,T、E只能是引用类型

2,

ArrayList list1 = new ArrayList<>(); //正确

ArrayList list2 = new ArrayList();  //错误

 调用泛型

 ArrayList list = new ArrayList();

//简写

ArrayList list1 = new ArrayList<>();

代码示例:

public class Test {
    public static void main(String[] args) {
        //不用泛型就是Object类型
        Student s= new Student<>();
        s.doSome(2);//可以是任意类型
        s.doOther("ccc");//只能是String类型
        s.doAny(new Object());//可以是任意类型
    }
}
class Student<标识符随便写>{
    //和方法当中同样的
    public void doSome(标识符随便写 o){
         System.out.println(o);
    }
    public void doOther(String s){
        System.out.println(s);
    }
    public<标识符随便写> void doAny(标识符随便写 o){
        System.out.println(o);
    }
}
结果:
2
ccc
java.lang.Object@1540e19d

枚举:

Java枚举(enum)详解 - 半边星 - 博客园

推荐文章:(以下内容很大一部分来自以下连接文章)

http://t.csdn.cn/3yeE4

1,枚举是一种引用数据类型

2,枚举编译后也是生成.class文件的

3,枚举:一枚一枚可以列出来的,才建议使用枚举类型

4,枚举中的每一个值可以看成是常量

5,结果只有两种情况,建议使用布尔类型。

        结果超过两种,并且还是可以一枚一枚列举出来的,建议使用枚举类型

6,枚举类中的成员属性名会自动添加---public static final 修饰

        是静态的,其他类可以直接使用“枚举名.成员属性名”进行获取枚举属性

枚举的定义:

enum 枚举类型名{

枚举值1,枚举值2

}

枚举的使用:

package task00;

import java.util.Scanner;

enum Season{
    spring,summer,autumn,winter;
//   常量有 spring, summer, autumn,winter,分别表示春天,夏天,秋天,冬天,系统会自动添加 public static final 修饰
}

public class SeasonEnum {
    public static void main(String[] args) {
        System.out.println("请输入季节"+"\n"+"1、春天"+"\n"+"2、夏天"+"\n"+"3、秋天"+"\n"+"4、冬天");
        Scanner scan =new Scanner(System.in);
        int seasons= scan.nextInt();
        change(seasons);
    }

    private static void change(int seasons) {
        Season season=Season.spring;
        switch (seasons){
            case 1:
                season=Season.spring;

                break;
            case 2:
                season=Season.summer;
                break;
            case 3:
                season=Season.autumn;
                break;
            case 4:
                season=Season.winter;
                break;
        }
        System.out.println(season);
    }
}

Java泛型和枚举_第1张图片

枚举常用方法:

enum 定义的枚举类默认继承了 java.lang.Enum 类,并实现了 java.lang.Serializable 和 java.lang.Comparable 两个接口。

values(), ordinal() 和 valueOf() 方法位于 java.lang.Enum 类中:

values() 返回枚举类中所有的值。
ordinal()方法可以找到每个枚举常量的索引,就像数组索引一样。

enum Season01{
    spring,summer,autumn,winter;
//   常量有 spring, summer, autumn,winter,
//分别表示春天,夏天,秋天,冬天,系统会自动添加 public static final 修饰
}

public class SeasonEnum01 {
    public static void main(String[] args) {

        //迭代获取每一个枚举元素的值.values()方法
        for (Season season:Season.values()){
            System.out.print(season+" ");
        }
        System.out.println("");
        //迭代获取每一个元素的索引
        for (Season season:Season.values()){
            System.out.println(season+"索引为"+season.ordinal());
        }
    }
}
结果:
spring summer autumn winter 
spring索引为0
summer索引为1
autumn索引为2
winter索引为3

枚举类成员

枚举跟普通类一样可以用自己的变量、方法和构造函数,构造函数只能使用 private 访问修饰符,所以外部无法调用。

枚举被设计成是单例模式,即枚举类型会由JVM在加载的时候,实例化枚举对象,你在枚举类中定义了多少个就会实例化多少个。JVM为了保证每一个枚举类元素的唯一实例,是不会允许外部进行new的,所以会把构造函数设计成private,防止用户生成实例,破坏唯一性。

注意一个细节:如果要为enum定义方法,那么必须在enum的最后一个实例尾部添加一个分号。此外,在enum中,必须先定义实例,不能将字段或方法定义在实例前面。否则,编译器会报错。

枚举既可以包含具体方法,也可以包含抽象方法。 如果枚举类具有抽象方法,则枚举类的每个实例都必须实现它。

package task00;

enum Season02{
    spring,summer,autumn,winter;
//   常量有 spring, summer, autumn,winter,分别表示春天,夏天,秋天,冬天,
//   系统会自动添加 public static final 修饰

    //    构造方法
    private Season02(){
        System.out.println("Constructor called for :" +this.toString());
    }
    public void SeasonInfo(){
        System.out.println("spring");
    }
}
public class SeasonEnum02 {
    public static void main(String[] args) {
        Season02 season=Season02.spring;
        System.out.println(season);
        season.SeasonInfo();
    }
}
结果:
Constructor called for :spring
Constructor called for :summer
Constructor called for :autumn
Constructor called for :winter
spring
spring

你可能感兴趣的:(java)