Java泛型
Java泛型概述
泛型在Java中被称之为”JAVA类型”,简称GJ。泛型是JavaSE平台1.5版本增加的新特性。泛型在Java中不是一种数据类型,是一种在编译时期的特殊语法,它能够让JVM识别从而确定在应用泛型的操作中体现泛型特点,帮助程序员在开发中从泛型中获得更高效和更安全数据的管理操作。
泛型由于不是一种Java的数据类型所以在运行时,JVM将使用擦除法将泛型描述还原成未应用泛型语法的规则进行执行。
泛型基本语法:<T>
泛型能够在代码书写过程中帮助程序员提高效率和数据类型安全。
泛型能够在编译阶段确定数据类型是否符合要求,规避错误发生。
泛型能否避免数据对象强制类型转换操作。
泛型也能够支持在动态下确定数据类型。
List<Department> depList = new ArrayList<Department>();
for(Department dep:depList){
System.out.println(dep.getName());
System.out.println(dep.getCode());
}
Java通配符泛型
List<?> numList = new ArrayList<>(); 使用通配符<?>的泛型,可以把任意类型的对象丢进去,但是缺点是,调用的时候只能用Object接收,并通过强制类型转换强转,这样就失去了泛型的一个省事儿的优势。所以最好还是使用确定了类型的泛型比较好些。
带泛型的类
public class GJClass<T>{ //这种属于隐式泛型。显示的一般有明确的数据类型如<Integer>
public String getClassName(T t){
return t.getClass().getName();
}
}
一般情况下隐式的用的比较多,显示的用得少。
带泛型的接口
public interface CountManager<T>{
double count(T t,double r);
double count(T t,double bottom,double height);
}
package src.com.xzit; import src.com.xzit.domain.Department; import src.com.xzit.domain.Employee; import src.com.xzit.imp.DepartmentMethod; import src.com.xzit.imp.EmployeeMethod; import java.util.Iterator; import java.util.List; import java.util.Scanner; /** * 测试类 * 此类完成测试按照给定的部门编号获取属于此部门的所有员工 * * */ public class TestByIdGetEmployee { public static void main(String[] args) { /* 此注释下获取提供给用户选则的所有部门信息(显示在控制台供用户选择输入部门编号)*/ //先new一个DepartmentMethod方法 DepartmentMethod dep = new DepartmentMethod(); //创建一个泛型是Department类的集合departments,用来接收调用foundAllDepList()方法返回的集合 List<Department> departments = dep.foundAllDepList(); //遍历输出部门的信息 for (Department dep2:departments){ System.out.println( "部门编号:"+dep2.getCdoe()+"\t" +"部门名称:"+dep2.getName()+"\t" +"部门成立日期:"+dep2.getCreateDate()); } //new一个Scanner接收用户输入 Scanner input = new Scanner(System.in); System.out.println("请输入您选择的部门编号:"); String depId = input.next(); /* 此注释下完成获取给定了选择部门id,属于此部门的所有员工在控制台输出显示*/ //先new一个EmployeeMethod类 EmployeeMethod emp = new EmployeeMethod(); //定义一个集合list0接收empListByDepId()方法的返回结果 List<Employee> list0 = emp.empListByDepId(depId); if (list0.size()==0){ System.out.println("没有查询结果!您的输入可能不正确"); }else { Iterator<Employee> iterator = list0.iterator();//获取迭代器 while(iterator.hasNext()){ Employee emp0 = iterator.next(); System.out.println( "员工姓名:"+emp0.getName() +"员工id:"+emp0.getCode() +"员工性别:"+emp0.getSex() +"员工出生日期:"+emp0.getBirth() +"员工入职日期:"+emp0.getEntry() +"员工部门编号:"+emp0.getDepCode() ); } } } }
package src.com.xzit; import src.com.xzit.domain.Employee; import src.com.xzit.imp.EmployeeMethod; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Scanner; /** * 测试类 * 此类测试按照用户给定的日期获取入职实际早于此日期的所有员工 * @author Administrator * */ public class TestByDateGetEmployee { public static void main(String[] args) throws ParseException { /* 此注释下编码实现从控制台接收用户输入的日期*/ Scanner input = new Scanner(System.in); System.out.println("请输入一个日期,格式yyyy-MM-dd"); String date0 = input.next(); Date date2 = new SimpleDateFormat("yyyy-MM-dd").parse(date0); /* 此注释下完成按照给定的日期获取入职早于此日期入职的所有员工并输出到控制台显示*/ //先new一个EmployeeMethod类 EmployeeMethod emp = new EmployeeMethod(); //定义一个集合list0接收empListByDepId()方法的返回结果 List<Employee> list0 = emp.empListByDepId(date2); if (list0.isEmpty()){ System.out.println("没有查询结果!您的输入可能不正确"); }else { Iterator<Employee> iterator = list0.iterator();//获取迭代器 while(iterator.hasNext()){ Employee emp0 = iterator.next(); System.out.println( "员工姓名:"+emp0.getName()+"\t" +"员工id:"+emp0.getCode()+"\t" +"员工性别:"+emp0.getSex()+"\t" +"员工出生日期:"+new SimpleDateFormat("yyyy-MM-dd").format(emp0.getBirth())+"\t" +"员工入职日期:"+new SimpleDateFormat("yyyy-MM-dd").format(emp0.getEntry())+"\t" +"员工部门编号:"+emp0.getDepCode()+"\t" ); } } } }
package src.com.xzit.imp; import src.com.xzit.dao.DepartmentDao; import src.com.xzit.db.DataBase; import src.com.xzit.domain.Department; import java.util.List; public class DepartmentMethod implements DepartmentDao { // 获取所有部门 @Override public List<Department> foundAllDepList() { DataBase dat = new DataBase(); List<Department> dep = dat.getDepTable(); return dep; } }
package src.com.xzit.imp; import src.com.xzit.dao.EmployeeDao; import src.com.xzit.db.DataBase; import src.com.xzit.domain.Employee; import java.util.ArrayList; import java.util.Date; import java.util.List; public class EmployeeMethod implements EmployeeDao { //先new一个数据库类 DataBase dat = new DataBase(); /* 按照给定的部门编号获取属于此部门的所有员工*/ @Override public List<Employee> empListByDepId(String depId) { //new一个容器集合用来存用户选择的部门的所有员工,一会儿返回这个集合 List<Employee> employeesResult = new ArrayList<Employee>(); //获取所有用户信息存进集合employees里 List<Employee> employees = dat.getEmpTable(); //遍历这个集合,一一对比用户的部门id for (Employee emp:employees){ if (depId.equals(emp.getDepCode())){ //如果部门的ID相等,就把这个用户存在容器集合里面 employeesResult.add(emp); } } //把集合作为返回结果 return employeesResult; } /* 获取入职时间早于给定时间before的所有员工*/ @Override public List<Employee> empListByDepId(Date before) { //new一个容器集合用来存入职日期早于用户输入日期的所有员工,一会儿返回这个集合 List<Employee> employeesResult = new ArrayList<Employee>(); //获取所有用户信息存进集合employees里 List<Employee> employees = dat.getEmpTable(); //遍历这个集合,比较用户的入职日期是不是早于用户输入的日期 for (Employee emp:employees){
// System.out.println(emp);
if (before.after(emp.getEntry())){ //如果用户输入的日期在员工的入职日期之后,就把这个员工加入要返回的集合 employeesResult.add(emp); } } return employeesResult; } }
package src.com.xzit.db; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import src.com.xzit.domain.Department; import src.com.xzit.domain.Employee; /** * 此类模仿数据库 * @author Administrator * */ public final class DataBase { /* 静态属性 depTable 模仿部门表*/ private static List<Department> depTable = new ArrayList<Department>(); /** /* 静态属性 empTable 模仿员工表*/ private static List<Employee> empTable = new ArrayList<Employee>(0); /* 静态块被加载时为empTable和depTable 进行初始化*/ static{ Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.YEAR,1990); calendar.add(Calendar.MONTH,7); calendar.add(Calendar.DATE,15); Department dep0 = new Department("code100","研发部",calendar.getTime()); Department dep2 = new Department("code200","市场部",calendar.getTime()); Department dep3 = new Department("code300","人事部",calendar.getTime()); //把部门对象放进List集合里 depTable.add(dep0); depTable.add(dep2); depTable.add(dep3); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); try { Employee emp0 = new Employee(); emp0.setBirth(sdf.parse("1988-6-23")); emp0.setCode(UUID.randomUUID().toString()); emp0.setDepCode(dep0.getCdoe()); emp0.setEntry(sdf.parse("2011-5-23")); emp0.setName("东方不败"); emp0.setSex("男"); Employee emp2 = new Employee(); emp2.setBirth(sdf.parse("1978-6-23")); emp2.setCode(UUID.randomUUID().toString()); emp2.setDepCode(dep0.getCdoe()); emp2.setEntry(sdf.parse("2000-5-23")); emp2.setName("任我行"); emp2.setSex("男"); Employee emp3 = new Employee(); emp3.setBirth(sdf.parse("1971-6-23")); emp3.setCode(UUID.randomUUID().toString()); emp3.setDepCode(dep0.getCdoe()); emp3.setEntry(sdf.parse("2005-5-23")); emp3.setName("岳不群"); emp3.setSex("男"); Employee emp4 = new Employee(); emp4.setBirth(sdf.parse("1988-6-23")); emp4.setCode(UUID.randomUUID().toString()); emp4.setDepCode(dep2.getCdoe()); emp4.setEntry(sdf.parse("2014-5-23")); emp4.setName("张无忌"); emp4.setSex("男"); Employee emp5 = new Employee(); emp5.setBirth(sdf.parse("1980-6-23")); emp5.setCode(UUID.randomUUID().toString()); emp5.setDepCode(dep2.getCdoe()); emp5.setEntry(sdf.parse("2016-5-23")); emp5.setName("向问天"); emp5.setSex("男"); Employee emp6 = new Employee(); emp6.setBirth(sdf.parse("1982-6-23")); emp6.setCode(UUID.randomUUID().toString()); emp6.setDepCode(dep2.getCdoe()); emp6.setEntry(sdf.parse("2015-5-23")); emp6.setName("任盈盈"); emp6.setSex("女"); Employee emp7 = new Employee(); emp7.setBirth(sdf.parse("1982-6-23")); emp7.setCode(UUID.randomUUID().toString()); emp7.setDepCode(dep2.getCdoe()); emp7.setEntry(sdf.parse("2013-5-23")); emp7.setName("马玉"); emp7.setSex("男"); Employee emp8 = new Employee(); emp8.setBirth(sdf.parse("1970-6-23")); emp8.setCode(UUID.randomUUID().toString()); emp8.setDepCode(dep3.getCdoe()); emp8.setEntry(sdf.parse("2000-5-23")); emp8.setName("于连婷"); emp8.setSex("男"); Employee emp9 = new Employee(); emp9.setBirth(sdf.parse("1972-6-23")); emp9.setCode(UUID.randomUUID().toString()); emp9.setDepCode(dep3.getCdoe()); emp9.setEntry(sdf.parse("2011-5-23")); emp9.setName("殷素素"); emp9.setSex("女"); Employee emp10 = new Employee(); emp10.setBirth(sdf.parse("1983-6-23")); emp10.setCode(UUID.randomUUID().toString()); emp10.setDepCode(dep3.getCdoe()); emp10.setEntry(sdf.parse("2012-5-23")); emp10.setName("小龙女"); emp10.setSex("女"); //把员工对象加进集合里 empTable.add(emp0); empTable.add(emp2); empTable.add(emp3); empTable.add(emp4); empTable.add(emp5); empTable.add(emp6); empTable.add(emp7); empTable.add(emp8); empTable.add(emp9); empTable.add(emp10); } catch (ParseException e) { e.printStackTrace(); } } public static List<Department> getDepTable() { return depTable; } public static List<Employee> getEmpTable() { return empTable; } }
package src.com.xzit.domain; import java.util.Date; /** * 部门实体类 * @author Administrator * */ public class Department { private String cdoe; // 部门编号(实际数据库部门表记录主键id.唯一性) private String name; // 部门名称,唯一性 private Date createDate; // 部门成立日期 /* geter and seter methods*/ public String getCdoe() { return cdoe; } public void setCdoe(String cdoe) { this.cdoe = cdoe; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } /** * 无参构造器 */ public Department() { } /** * 有参构造器 * @param cdoe * @param name * @param createDate */ public Department(String cdoe, String name, Date createDate) { this.cdoe = cdoe; this.name = name; this.createDate = createDate; } }
package src.com.xzit.domain; import java.util.Date; /** * 员工实体类 * @author Administrator * */ public class Employee { private String code; // 员工编号(实际数据库员工表记录主键id.唯一性) private String name; // 员工姓名 private String sex; // 性别 private Date birth; // 出生日期 private Date entry; // 入职日期 private String depCode; // 部门编号,必需是已有部门对象的code值,标识员工所在部门 public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } public Date getEntry() { return entry; } public void setEntry(Date entry) { this.entry = entry; } public String getDepCode() { return depCode; } public void setDepCode(String depCode) { this.depCode = depCode; }
@Override public String toString() { return "Employee{" + "code='" + code + '\'' + ", name='" + name + '\'' + ", sex='" + sex + '\'' + ", birth=" + birth + ", entry=" + entry + ", depCode='" + depCode + '\'' + '}'; }
}
package src.com.xzit.dao; import java.util.List; import src.com.xzit.domain.Department; /** * 部门数据访问的接口 * @author Administrator * */ public interface DepartmentDao { List<Department> foundAllDepList(); // 获取所有部门 }
package src.com.xzit.dao; import java.util.Date; import java.util.List; import src.com.xzit.domain.Employee; /** * 员工数据访问的接口 * @author Administrator * */ public interface EmployeeDao { /* 按照给定的部门编号获取属于此部门的所有员工*/ List<Employee> empListByDepId(String depId); /* 获取入职时间早于给定时间before的所有员工*/ List<Employee> empListByDepId(Date before); }
写作业的时候遇到的一个空指针异常的处理结果:
Ivan 22:39:00
报错是空指针异常,那您是如何知道是这一块代码出错了呢
史老师 22:39:51
这个很容易啊,报空指针,要不就是对象为空,要不就是对象属性为空
史老师 22:40:20
我用toString,循环的时候,先把你所有的对象打印一下,就看到了第9个对象的这个属性是null值
史老师 22:40:36
那很容易判断,就是在赋值的时候,这个对象的属性没赋上
Ivan 22:40:47
原来如此
史老师 22:41:19
生成了一个toString
史老师 22:41:20
Ivan 22:41:46
是需要自己写一个toString来看一下?通过debug是看不出的?
史老师 22:43:08
能看出来,不好看,我用toString打印到控制台上,很方便看
史老师 22:43:28
这里报错了
史老师 22:43:46
我把你下面报错的代码注掉了,先打印了一下对象
史老师 22:44:41
打印到控制台,很明显看到一个值不对
史老师 22:44:42
史老师 22:44:55
第9个对象,就直接定位过去了
Ivan 22:48:55
原来是这样,学到了