package com.peace.generic;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.junit.Test;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
*
* @ClassName: GenricDemo01
* @Description: 测试泛型
* @author peace w_peace@163.com
* @date 3 Dec 2015 8:17:28 pm
*/
//泛型类的编写:就是在类名之后加上<T> 或者多个:<T,S> 泛型接口与之类似;
public class GenricDemo01<T> {
//可以直接定义一个引用
T t;
//t=new T();但是不能实例化
@Test
//XML配置方式,使用C3P0连接池管理连接
public void testXML() throws Exception {
// 创建c3p0连接池核心工具类
// 自动加载src下c3p0的配置文件【c3p0-config.xml】
ComboPooledDataSource dataSource = new ComboPooledDataSource();// 使用默认的配置
PreparedStatement pstmt = null;
// ---> 从连接池对象中,获取连接对象
Connection con = dataSource.getConnection();
// 执行更新
con.prepareStatement("delete from admin where id=12").executeUpdate();
// 关闭
con.close();
}
@Test
public void testGenerc(){
//1.集合的声明,不值名类型
List list=new ArrayList<>();
list.add(1);
list.add("dddd");
//获得字符串,当不写清楚放入的类型时,这里可以编译通过但是运行时报出异常
//String s=(String)list.get(0);
//System.out.println(s);
//2.使用泛型:
//List<int> a;不能放基础类型;
List<String> list2=new ArrayList<>();
list2.add("234");
//list2.add(234);当指明了字符串类型时,编译时就会出粗
//3.泛型只在编译时期有效,编译后的字节码文件中不存在有泛型信息!
if(list.getClass().equals(list2.getClass())==true)
System.out.println("两者还是属于相同的类型");
}
/*
* 当用泛型做函数参数时,一定要注意由于泛型的擦除,形如下面的两个方法不是重载会报错:
* 编译不能通过
*/
/* public void save(List<Integer> i){}
public void save(List<String> s){}*/
/**
*
* @Title: generic
* @Description: 泛型方法的编写:
* 要求:在返回值之前加上使用到的泛型标志:<K,T>
*/
public static <K,F> F generic(K m1){
return null;
}
/*
* 调用泛型方法:
* 只需要将对应的参数传入即可,不需要像泛型类一样将泛型写清楚:如List<String>
*/
@Test
public void testMethod(){
//直接调用就行;方法会自己匹配型号;此时方法匹配的型号:k为Date T为String
String s=generic(new Date());
}
//下面测试关键字:?,extend,super
public void testKeys(){
//list3.add(new Person());
//测试有界类型:
Stats<Person> person=new Stats();
Stats<Student>student=new Stats();
Stats<Teacher>teacher=new Stats();
Stats<High>high=new Stats();
//Stats<String> s=new Stats(); 放入的类型必须为Person的子类;
String s=new String();
//测试?
save1(person);
save1(student);
save1(high);
save1(high);
//save1(s);
//测试extends
save2(student);
save2(high);
//save2(teacher);
//save2(person);
//测试super
save3(student);
save3(person);
//save3(teacher);
//save3(high);
}
//方法 测试用 ?号能传入任何继承自person的参数的Stats
public void save1(Stats<?>s){
//能够获取
Person p = s.getP();
//不能操作 泛型定义的P引用
//s.setP(p);
//能操作其他应用
s.setS("peace");
}
//测试extends 能传入继承自Studnet的参数或者Student的Stats
public void save2(Stats<? extends Student>s){
//能够获取
Person p = s.getP();
//不能操作 泛型定义的P引用
//s.setP(p);
//能操作其他应用
s.setS("peace");
}
//测试super 能传入Studnet的父类和Studnet
public void save3(Stats<? super Student>s){
//能够获取
Student p = (Student)s.getP();
//能写入
s.setP(p);
}
}
//泛型类型确定: 实现泛型接口的类也是抽象,那么类型在具体的实现中确定或创建泛型类的时候确定
class Test1<T> extends GenricDemo01<T>{
}
//泛型类型确定: 在业务实现类中直接确定接口的类型
class Test2 extends GenricDemo01<String>{
}
//建立四个类用于测试:
class Person{
}
//继承自person类
class Student extends Person{
}
//继承自person类
class Teacher extends Person{
}
//继承自Student
class High extends Student{
}
//限制传入类型必须为Person或者其子类,可以限定多个接口和一个类
class Stats<T extends Person>{
T p;
String s;
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public T getP() {
return p;
}
public void setP(T p) {
this.p = p;
}
}