Java基础_泛型_枚举_注解

泛型

只有指定类型加入泛型中才是安全的
这样读取的对象不需要强制转换类型

泛型,JDK1.5新加入的,解决数据类型的安全性问题,其主要原理是在类声明时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这样在类声明或实例化时只要指定好需要的具体的类型即可。
Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。同时,代码更加简洁、健壮

注意

Java中的泛型,只在编译阶段有效。在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。也就是说,泛型信息不会进入到运行时阶段

泛型类
1.在不指定的情况下,默认为Object类型的
2.泛型不同的的对象之间不能够相互赋值

import java.util.ArrayList;
import java.util.List;
public class Test {
	public static void main(String[] args) {
		List list = new ArrayList();
		list.add(111);
		list.add("sss");
		list.add(true);
		//需求,只能在集合中存字符串
		List<String> l = new ArrayList<String>();
		l.add("xx");
//		l.add(true);//这个是编译期发现的问题
		
		A<String> a1 = new A<String>();//在new A的对象指定泛型的类型String
		a1.serKey("xxxx");//对象使用serKey(T key)方法,中的key形参就是String
		String s = a1.getKey();//T getKey(),返回值就有new对象确定返回值是String
		
		A<Integer> a2 = new A<Integer>();
		a2.serKey(1);
		Integer i = a2.getKey();
		
		A a3 = new A();//不指定泛型,相当于指定了一个Object类型
//		A<Object> a3 = new A<Object>();
		a3.serKey(new Object());
		Object obj = a3.getKey();
		
		//同样的类,但是在new对象时泛型指定不同的数据类型,这些对象不能互相赋值
//		a1 = a2;
	}
}
/**
 * 此次的泛型T可以任意的取名,A,B,V
 * 一般使用T,意为type

 * @param <T>
 */
class A<T>{
	private T key;
	
	public void serKey(T key){
		this.key = key;
	}
	public T getKey(){
		return this.key;
	}
}

泛型接口

//定义一个泛型接口
interface Generator<T> {
T next();
}
public class Test1 {
	public static void main(String[] args) {
//		B1<Object> b1 = new B1<Object>();
//		B1<String> b2 = new B1<String>();
//		
//		B2 b3 = new B2();
		
		Cc<Object> c = new Cc<Object>();
		c.test("xxx");
		//泛型方法,在调用之前没有固定的数据类型
		//在调用时,传入的参数是什么类型,就会把泛型改成什么类型
		//也就是说,泛型方法会在调用时确定泛型距离数据类型
		Integer i = c.test1(2);//传递的参数是Integer,泛型就固定成Integer,返回值就是Integer
		Boolean b = c.test1(true);//传递的参数是Boolean,泛型就固定成Boolean,返回值就是Boolean
	}
}

interface IB<T>{
	T test(T t);
}

/**
 * 未传入泛型实参时,与泛型类的定义相同,在声明类的时候,需将泛型的声明也一起加到类中
 * @author lby
 *
 * @param <T>
 */
class B1<T> implements IB<T>{

	@Override
	public T test(T t) {
		return t;
	}
	
}

/**
 * 如果实现接口时指定接口的泛型的具体数据类型
 * 这个类实现接口所有方法的位置都要泛型替换实际的具体数据类型
 * @author lby
 *
 */
class B2 implements IB<String>{

	@Override
	public String test(String t) {
		return null;
	}
	
}

class Cc<E>{
	private E e;
	
	/**
	 * 静态方法的泛型方法
	 * @param t
	 */
	public static <T> void test3(T t){
		//在静态方法中,不能使用类定义泛型,如果要使用泛型,只能使用静态方法自己定义的泛型
//		System.out.println(this.e);
		System.out.println(t);
	}
	
	/**
	 * 无返回值的泛型方法
	 * @param s
	 */
	public <T> void test(T s){
		//在类上定义的泛型,可以在普通的方法中使用
		System.out.println(this.e);
		T t = s;
	}
	
	/**
	 * 有返回值的泛型方法
	 * @param s
	 */
	public <T> T test1(T s){
		return s;
	}
	
	/**
	 * 形参为可变参数的泛型方法
	 * @param strs
	 */
	public <T> void test2(T... strs){
		for(T s : strs){
			System.out.println(s);
		}
	}
}

通配符

/**
 * 不确定集合中的元素具体的数据类型
 * 使用?表示所有类型
 * @param list
 */
public void test(List<?> list){
System.out.println(list);
}
 <? extends Person>     (无穷小 , Person]
 只允许泛型为Person及Person子类的引用调用

 <? super Person >      [Person , 无穷大)
 只允许泛型为Person及Person父类的引用调用

<? extends Comparable>
只允许泛型为实 现Comparable接口的实现类的引用调用

枚举和注解

enum 定义枚举类

JDK 1.5 新增的 enum 关键字用于定义枚举类
枚举类和普通类的区别:
使用 enum 定义的枚举类默认继承了 java.lang.Enum 类
枚举类的构造器只能使用 private 访问控制符
枚举类的所有实例必须在枚举类中显式列出(, 分隔 ; 结尾). 列出的实例系统会自动添加 public static final 修饰
所有的枚举类都提供了一个 values 方法, 该方法可以很方便地遍历所有的枚举值
JDK 1.5 中可以在 switch 表达式中使用枚举类的对象作为表达式, case 子句可以直接使用枚举值的名字, 无需添加枚举类作为限定
若枚举只有一个成员, 则可以作为一种单子模式的实现方式

枚举类对象的属性不应允许被改动, 所以应该使用 private final 修饰
枚举类使用 private final 修饰的属性应该在构造器中为其赋值
若枚举类显式的定义了带参数的构造器, 则在列出枚举值时也必须对应的传入参数

实现接口的枚举类

和普通 Java 类一样枚举类可以实现一个或多个接口
若需要每个枚举值在调用实现的接口方法呈现出不同的行为方式, 则可以让每个枚举值分别来实现该方法

public class Test3 {
	public static void main(String[] args) {
		//Season.SPRING,这段执行就是获取一个Season的对象
		Season spring = Season.SPRING;
		spring.showInfo();
		
		Season summer = Season.SUMMER;
		summer.showInfo();
		
		Season spring1 = Season.SPRING;
		//每次执行Season.SPRING获得是相同的对象,枚举类中的每个枚举都是单例模式的
		System.out.println(spring.equals(spring1));
		spring1.test();
		
	}
}

enum Season implements ITest{
	SPRING("春天","春暖花开"),//此处相当于在调用有参的私有构造private Season(String name,String desc)
	SUMMER("夏天","炎炎夏日"),
	AUTUMN("秋天","秋高气爽"),
	WINTER("冬天","寒风凛冽");

	private final String name;
	private final String desc;
	private Season(String name,String desc){
		this.name = name;
		this.desc = desc;
	}
	public void showInfo(){
		System.out.println(this.name + ": " + this.desc);
	}

	@Override
	public void test() {
		System.out.println("这是实现的ITest接口的test方法");
	}
}
interface ITest{
	void test();
}

注解

注解概述
从 JDK 5.0 开始, Java 增加了对元数据(MetaData) 的支持, 也就是 Annotation(注释)
Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 并执行相应的处理. 通过使用 Annotation, 程序员可以在不改变原有逻辑的情况下, 在源文件中嵌入一些补充信息.
Annotation 可以像修饰符一样被使用, 可用于修饰包,类, 构造器, 方法, 成员变量, 参数, 局部变量的声明, 这些信息被保存在 Annotation 的 “name=value” 对中.
Annotation 能被用来为程序元素(类, 方法, 成员变量等) 设置元数据

使用 Annotation 时要在其前面增加 @ 符号, 并把该 Annotation 当成一个修饰符使用. 用于修饰它支持的程序元素

三个基本的 Annotation:
@Override: 限定重写父类方法, 该注释只能用于方法
@Deprecated: 用于表示某个程序元素(, 方法等)已过时
@SuppressWarnings: 抑制编译器警告. 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值