java.text.DateFormat
是日期/时间格式化子类的抽象类,我们通过这个类可以帮我们完成日期和文本之间的转换,也就是可以在Date对象与String对象之间进行来回转换。
由于DateFormat为抽象类,不能直接使用,所以需要常用的子类java.text.SimpleDateFormat
。这个类需要一个模式(格式)来指定格式化或解析的标准。构造方法为:
public SimpleDateFormat(String pattern)
:用给定的模式和默认语言环境的日期格式符号构造SimpleDateFormat。参数pattern是一个字符串,代表日期时间的自定义格式。常用的格式规则为:
标识字母(区分大小写) | 含义 |
---|---|
y | 年 |
M | 月 |
d | 日 |
H | 时 |
m | 分 |
s | 秒 |
备注:更详细的格式规则,可以参考SimpleDateFormat类的API文档。
DateFormat类的常用方法有:
public String format(Date date)
:将Date对象格式化为字符串。
public String format(Object time)
:把时间毫秒值格式化成我们喜欢的形式。
public Date parse(String source)
:将字符串解析为Date对象。
public class SimpleDateFormatDemo {
public static void main(String[] args) throws ParseException {
//格式化:从 Date 到 String
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String s = sdf.format(d);
System.out.println(s);
System.out.println("--------");
//从long到String
//a.得到此刻的时间对象
Datedate=new Date();
System.out.printin(date);
//b.得到当前时间的时间毫秒值
long time = date.getTime();
time+=121*1000;
//c.格式化时间毫秒值
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
System.out.println(sdf.format (time));
System.out.println("--------");
//从 String 到 Date
String ss = "2048-08-09 11:11:11";
//ParseException
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date dd = sdf2.parse(ss);
System.out.println(dd);
}
}
小结:DateFormat可以将Date对象和字符串相互转换。
方法名 | 说明 |
---|---|
public static Calendar getInstance() | 获取一个它的子类GregorianCalendar对象。 |
public int get(int field) | 获取某个字段的值。field参数表示获取哪个字段的值, 可以使用Calender中定义的常量来表示: Calendar.YEAR : 年 Calendar.MONTH :月 Calendar.DAY_OF_MONTH:月中的日期 Calendar.HOUR:小时 Calendar.MINUTE:分钟 Calendar.SECOND:秒 Calendar.DAY_OF_WEEK:星期 |
public void set(int field,int value) | 设置某个字段的值 |
public void add(int field,int amount) | 为某个字段增加/减少指定的值 |
public class Demo {
public static void main(String[] args) {
//1.获取一个GregorianCalendar对象
Calendar instance = Calendar.getInstance();//获取子类对象
//2.打印子类对象
System.out.println(instance);
//3.获取属性
int year = instance.get(Calendar.YEAR);
int month = instance.get(Calendar.MONTH) + 1;//Calendar的月份值是0-11
int day = instance.get(Calendar.DAY_OF_MONTH);
int hour = instance.get(Calendar.HOUR);
int minute = instance.get(Calendar.MINUTE);
int second = instance.get(Calendar.SECOND);
int week = instance.get(Calendar.DAY_OF_WEEK);//返回值范围:1--7,分别表示:"星期日","星期一","星期二",...,"星期六"
System.out.println(year + "年" + month + "月" + day + "日" +
hour + ":" + minute + ":" + second);
System.out.println(getWeek(week));
}
//查表法,查询星期几
public static String getWeek(int w) {//w = 1 --- 7
//做一个表(数组)
String[] weekArray = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
// 索引 [0] [1] [2] [3] [4] [5] [6]
//查表
return weekArray[w - 1];
}
}
public class Demo {
public static void main(String[] args) {
//设置属性——set(int field,int value):
Calendar c1 = Calendar.getInstance();//获取当前日期
//计算班长出生那天是星期几(假如班长出生日期为:1998年3月18日)
c1.set(Calendar.YEAR, 1998);
c1.set(Calendar.MONTH, 3 - 1);//转换为Calendar内部的月份值
c1.set(Calendar.DAY_OF_MONTH, 18);
int w = c1.get(Calendar.DAY_OF_WEEK);
System.out.println("班长出生那天是:" + getWeek(w));
}
//查表法,查询星期几
public static String getWeek(int w) {//w = 1 --- 7
//做一个表(数组)
String[] weekArray = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
// 索引 [0] [1] [2] [3] [4] [5] [6]
//查表
return weekArray[w - 1];
}
}
public class Demo {
public static void main(String[] args) {
//计算200天以后是哪年哪月哪日,星期几?
Calendar c2 = Calendar.getInstance();//获取当前日期
c2.add(Calendar.DAY_OF_MONTH, 200);//日期加200
int y = c2.get(Calendar.YEAR);
int m = c2.get(Calendar.MONTH) + 1;//转换为实际的月份
int d = c2.get(Calendar.DAY_OF_MONTH);
int wk = c2.get(Calendar.DAY_OF_WEEK);
System.out.println("200天后是:" + y + "年" + m + "月" + d + "日" + getWeek(wk));
}
//查表法,查询星期几
public static String getWeek(int w) {//w = 1 --- 7
//做一个表(数组)
String[] weekArray = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
// 索引 [0] [1] [2] [3] [4] [5] [6]
//查表
return weekArray[w - 1];
}
}
方法名 | 说明 |
---|---|
public static int abs(int a) | 获取参数a的绝对值: |
public static double ceil(double a) | 向上取整 |
public static double floor(double a) | 向下取整 |
public static double pow(double a, double b) | 获取a的b次幂 |
public static long round(double a) | 四舍五入取整 |
public class Demo {
public static void main(String[] args) {
System.out.println("-5的绝对值:" + Math.abs(-5));//5
System.out.println("3.4向上取整:" + Math.ceil(3.4));//4.0
System.out.println("3.4向下取整:" + Math.floor(3.4));//3.0
System.out.println("2的8次幂:" + Math.pow(2, 8));//256.0
System.out.println("3.2四舍五入:" + Math.round(3.2));//3
System.out.println("3.5四舍五入:" + Math.round(3.5));//4
}
}
java.lang.System
类中提供了大量的静态方法,可以获取与系统相关的信息或系统级操作。
方法名 | 说明 |
---|---|
public static void exit(int status) | 终止当前运行的 Java 虚拟机,非零表示异常终止 |
public static long currentTimeMillis() | 返回当前时间(以毫秒为单位) |
在控制台输出1-10000,计算这段代码执行了多少毫秒
import java.util.Date;
//验证for循环打印数字1-9999所需要使用的时间(毫秒)
public class SystemDemo {
public static void main(String[] args) {
//获取当前时间毫秒值
System.out.println(System.currentTimeMillis());
//计算程序运行时间
long start = System.currentTimeMillis();
for (int i = 1; i <= 10000; i++) {
System.out.println(i);
}
long end = System.currentTimeMillis();
System.out.println("共耗时毫秒:" + (end - start));
}
}
拓展:System.arraycopy()用来复制数组
arraycopy(object var0,int varl,object var2,int var3,int var4);
*参数一:原数组
*参数二:从原数组的哪个位置开始赋值。
*参数三:目标数组
*参数四:赋值到目标数组的哪个位置
*参数五:赋值几个。
浮点数做运算精度问题;
看程序说结果:
public static void main(String[] args) {
System.out.println(0.09 + 0.01);
System.out.println(1.0 - 0.32);
System.out.println(1.015 * 100);
System.out.println(1.301 / 100);
}
相关内容 | 具体描述 |
---|---|
包 | java.math 使用时需要导包 |
类声明 | public class BigDecimal extends Number implements Comparable |
描述 | BigDecimal类提供了算术,缩放操作,舍入,比较,散列和格式转换的操作。提供了更加精准的数据计算方式 |
不推荐直接new对象,在实际开发国过程中,我们经常遇到的是把double类型的数据转化为BigDecimal
用静态方法valueOf()
构造方法名 | 描述 |
---|---|
BigDecimal(double val) | 将double类型的数据封装为BigDecimal对象 |
BigDecimal(String val) | 将 BigDecimal 的字符串表示形式转换为 BigDecimal |
注意:推荐使用第二种方式,第一种存在精度问题;
BigDecimal类中使用最多的还是提供的进行四则运算的方法,如下:
方法声明 | 描述 |
---|---|
public BigDecimal add(BigDecimal value) | 加法运算 |
public BigDecimal subtract(BigDecimal value) | 减法运算 |
public BigDecimal multiply(BigDecimal value) | 乘法运算 |
public BigDecimal divide(BigDecimal value) | 除法运算 |
double a = 0.1;
double b =0.2;
double c = a +b;
System.out.println(c);
//1.把浮点数转换成大数据附廉运算
BigDecimal al = BigDecimal.valueOf(a);
BigDecimal b1 = BigDecimal.valueOf(b);
//BigDecima1c1=a1.add(b1);//加法
BigDecimal c1=al.divide(b1);//除法
System.out.println(c1);
//结果可能需要继续使用!!!
//BigDecimal,只是解决精度问题的手段,double数据才是我们的目的!!
double rs = c1.doublevalue ();
System.out.println(rs);
注意:对于divide方法来说,如果除不尽的话,就会出现java.lang.ArithmeticException异常。此时可以使用divide方法的另一个重载方法;
BigDecimal divide(BigDecimal divisor, int scale, int roundingMode): divisor:除数对应的BigDecimal对象;scale:精确的位数;roundingMode取舍模式
小结:Java中小数运算有可能会有精度问题,如果要解决这种精度问题,可以使用BigDecimal
public class Demo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的QQ号码:");
String qq = sc.next();
System.out.println(checkQQ(qq));
}
//我们自己编写代码,验证QQ号码
private static boolean checkQQ(String qq) {
//1.验证5--15位
if(qq.length() < 5 || qq.length() > 15){
return false;
}
//2.必须都是数字;
for(int i = 0;i < qq.length() ; i++){
char c = qq.charAt(i);
if(c < '0' || c > '9'){
return false;
}
}
//3.首位不能是0;
char c = qq.charAt(0);
if(c == '0'){
return false;
}
return true;//验证通过
}
}
public class Demo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的QQ号码:");
String qq = sc.next();
System.out.println(checkQQ2(qq));
}
//使用正则表达式验证
private static boolean checkQQ2(String qq){
String regex = "[1-9]\\d{4,14}";//正则表达式
return qq.matches(regex);
}
}
上面程序checkQQ2()方法中String类型的变量regex就存储了一个"正则表达式 ",而这个正则表达式就描述了我们需要的三个规则。matches()方法是String类的一个方法,用于接收一个正则表达式,并将"本对象"与参数"正则表达式"进行匹配,如果本对象符合正则表达式的规则,则返回true,否则返回false。
我们接下来就重点学习怎样写正则表达式
public class Demo {
public static void main(String[] args) {
String str = "ead";
//1.验证str是否以h开头,以d结尾,中间是a,e,i,o,u中某个字符
String regex = "h[aeiou]d";
System.out.println("1." + str.matches(regex));
//2.验证str是否以h开头,以d结尾,中间不是a,e,i,o,u中的某个字符
regex = "h[^aeiou]d";
System.out.println("2." + str.matches(regex));
//3.验证str是否a-z的任何一个小写字符开头,后跟ad
regex = "[a-z]ad";
System.out.println("3." + str.matches(regex));
//4.验证str是否以a-d或者m-p之间某个字符开头,后跟ad
regex = "[[a-d][m-p]]ad";
System.out.println("4." + str.matches(regex));
}
}
public class Demo {
public static void main(String[] args) {
String str = "had";
//1.要求字符串是小写辅音字符开头,后跟ad
String regex = "[a-z&&[^aeiou]]ad";
System.out.println("1." + str.matches(regex));
//2.要求字符串是aeiou中的某个字符开头,后跟ad
regex = "[a|e|i|o|u]ad";//这种写法相当于:regex = "[aeiou]ad";
System.out.println("2." + str.matches(regex));
}
}
public class Demo {
public static void main(String[] args) {
String str = "258";
//1.验证str是否3位数字
String regex = "\\d\\d\\d";
System.out.println("1." + str.matches(regex));
//2.验证手机号:1开头,第二位:3/5/8,剩下9位都是0-9的数字
str = "13513153355";//要验证的字符串
regex = "1[358]\\d\\d\\d\\d\\d\\d\\d\\d\\d";//正则表达式
System.out.println("2." + str.matches(regex));
//3.验证字符串是否以h开头,以d结尾,中间是任何字符
str = "had";//要验证的字符串
regex = "h.d";//正则表达式
System.out.println("3." + str.matches(regex));
//4.验证str是否是:had.
str = "had.";//要验证的字符串
regex = "had\\.";//\\.代表'.'符号,因为.在正则中被预定义为"任意字符",不能直接使用
System.out.println("4." + str.matches(regex));
}
}
public class Demo {
public static void main(String[] args) {
String str = "";
//1.验证str是否是三位数字
str = "012";
String regex = "\\d{3}";
System.out.println("1." + str.matches(regex));
//2.验证str是否是多位数字
str = "88932054782342";
regex = "\\d+";
System.out.println("2." + str.matches(regex));
//3.验证str是否是手机号:
str = "13813183388";
regex = "1[358]\\d{9}";
System.out.println("3." + str.matches(regex));
//4.验证小数:必须出现小数点,但是只能出现1次
String s2 = "3.1";
regex = "\\d*\\.{1}\\d+";
System.out.println("4." + s2.matches(regex));
//5.验证小数:小数点可以不出现,也可以出现1次
regex = "\\d+\\.?\\d+";
System.out.println("5." + s2.matches(regex));
//6.验证小数:要求匹配:3、3.、3.14、+3.14、-3.
s2 = "-3.";
regex = "[+-]\\d+\\.?\\d*";
System.out.println("6." + s2.matches(regex));
//7.验证qq号码:1).5--15位;2).全部是数字;3).第一位不是0
s2 = "1695827736";
regex = "[1-9]\\d{4,14}";
System.out.println("7." + s2.matches(regex));
}
}
public class Demo {
public static void main(String[] args) {
String str = "DG8FV-B9TKY-FRT9J-99899-XPQ4G";
//验证这个序列号:分为5组,每组之间使用-隔开,每组由5位A-Z或者0-9的字符组成
String regex = "([A-Z0-9]{5}-){4}[A-Z0-9]{5}";
System.out.println(str.matches(regex));
}
}
String类的split()方法原型:
public String[] split(S//参数regex就是一个正则表达式。可以将当前字符串中匹配regex正则表达式的符号作为"分隔符"来切割字符串。
代码示例:
public class Demo {
public static void main(String[] args) {
String str = "18 4 567 99 56";
String[] strArray = str.split(" +");
for (int i = 0; i < strArray.length; i++) {
System.out.println(strArray[i]);
}
}
}
public String replaceAll(String regex,String newStr)//参数regex就是一个正则表达式。可以将当前字符串中匹配regex正则表达式的字符串替换为newStr。
public class Demo {
public static void main(String[] args) {
//将下面字符串中的"数字"替换为"*"
String str = "jfdk432jfdk2jk24354j47jk5l31324";
System.out.println(str.replaceAll("\\d+", "*"));
}
}
Java提供了两个类型系统,基本类型与引用类型,使用基本类型在于效率,然而很多情况,会创建对象使用,因为对象可以做更多的功能,如果想要我们的基本类型像对象一样操作,就可以使用基本类型对应的包装类,如下:
基本类型 | 对应的包装类(位于java.lang包中) |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
Integer类概述
包装一个对象中的原始类型 int 的值
Integer类构造方法及静态方法
方法名 | 说明 |
---|---|
public Integer(int value) | 根据 int 值创建 Integer 对象(过时) |
public Integer(String s) | 根据 String 值创建 Integer 对象(过时) |
public static Integer valueOf(int i) | 返回表示指定的 int 值的 Integer 实例 |
public static Integer valueOf(String s) | 返回保存指定String值的 Integer 对象 |
public class IntegerDemo {
public static void main(String[] args) {
//public Integer(int value):根据 int 值创建 Integer 对象(过时)
Integer i1 = new Integer(100);
System.out.println(i1);
//public Integer(String s):根据 String 值创建 Integer 对象(过时)
Integer i2 = new Integer("100");
//Integer i2 = new Integer("abc"); //NumberFormatException
System.out.println(i2);
System.out.println("--------");
//public static Integer valueOf(int i):返回表示指定的 int 值的 Integer 实例
Integer i3 = Integer.valueOf(100);
System.out.println(i3);
//public static Integer valueOf(String s):返回保存指定String值的Integer对象
Integer i4 = Integer.valueOf("100");
System.out.println(i4);
}
}
基本类型与对应的包装类对象之间,来回转换的过程称为”装箱“与”拆箱“:
用Integer与 int为例:(看懂代码即可)
基本数值---->包装对象
Integer i = new Integer(4);//使用构造函数函数
Integer iii = Integer.valueOf(4);//使用包装类中的valueOf方法
包装对象---->基本数值
int num = i.intValue();
由于我们经常要做基本类型与包装类之间的转换,从Java 5(JDK 1.5)开始,基本类型与包装类的装箱、拆箱动作可以自动完成。例如:
Integer i = 4;//自动装箱。相当于Integer i = Integer.valueOf(4);
i = i + 5;//等号右边:将i对象转成基本数值(自动拆箱) i.intValue() + 5;
//加法运算完成后,再次装箱,把基本数值转成对象。
public class IntegerDemo {
public static void main(String[] args) {
//int --- String
int number = 100;
//方式1
String s1 = number + "";
System.out.println(s1);
//方式2
//public static String valueOf(int i)
String s2 = String.valueOf(number);
System.out.println(s2);
System.out.println("--------");
}
}
除了Character类之外,其他所有包装类都具有parseXxx静态方法可以将字符串参数转换为对应的基本类型:
public static byte parseByte(String s)
:将字符串参数转换为对应的byte基本类型。public static short parseShort(String s)
:将字符串参数转换为对应的short基本类型。public static int parseInt(String s)
:将字符串参数转换为对应的int基本类型。public static long parseLong(String s)
:将字符串参数转换为对应的long基本类型。public static float parseFloat(String s)
:将字符串参数转换为对应的float基本类型。public static double parseDouble(String s)
:将字符串参数转换为对应的double基本类型。public static boolean parseBoolean(String s)
:将字符串参数转换为对应的boolean基本类型。代码使用(仅以Integer类的静态方法parseXxx为例)如:
public class IntegerDemo {
public static void main(String[] args) {
//String --- int
String s = "100";
//方式1:String --- Integer --- int
Integer i = Integer.valueOf(s);
//public int intValue()
int x = i.intValue();
System.out.println(x);
//方法1:自动拆箱
int x = Integer.valueOf(s);
//方式2
//public static int parseInt(String s)
int y = Integer.parseInt(s);
System.out.println(y);
}
}
注意:如果字符串参数的内容无法正确转换为对应的基本类型,则会抛出
java.lang.NumberFormatException
异常。
在前面学习集合时,我们都知道集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object类型。当我们在取出每一个对象,并且进行相应的操作,这时必须采用类型转换。
大家观察下面代码:
public class GenericDemo {
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add("abc");
coll.add("itcast");
coll.add(5);//由于集合没有做任何限定,任何类型都可以给其中存放
Iterator it = coll.iterator();
while(it.hasNext()){
//需要打印每个字符串的长度,就要把迭代出来的对象转成String类型
String str = (String) it.next();
System.out.println(str.length());
}
}
}
程序在运行时发生了问题java.lang.ClassCastException
为什么会发生类型转换异常呢?
我们来分析下:由于集合中什么类型的元素都可以存储。导致取出时强转引发运行时 ClassCastException。 怎么来解决这个问题呢?
Collection虽然可以存储各种对象,但实际上通常Collection只存储同一类型对象。例如都是存储字符串对象。因此在JDK5之后,新增了泛型(Generic)语法,让你在设计API时可以指定类或方法支持泛型,这样我们使用API的时候也变得更为简洁,并得到了编译时期的语法检查。
tips:一般在创建对象时,将未知的类型确定具体的类型。当没有指定泛型时,默认类型为Object类型。
上一节只是讲解了泛型的引入,那么泛型带来了哪些好处呢?
通过我们如下代码体验一下:
public class GenericDemo2 {
public static void main(String[] args) {
Collection<String> list = new ArrayList<String>();
list.add("abc");
list.add("itcast");
// list.add(5);//当集合明确类型后,存放类型不一致就会编译报错
// 集合已经明确具体存放的元素类型,那么在使用迭代器的时候,迭代器也同样会知道具体遍历元素类型
Iterator<String> it = list.iterator();
while(it.hasNext()){
String str = it.next();
//当使用Iterator控制元素类型后,就不需要强转了。获取到的元素直接就是String类型
System.out.println(str.length());
}
}
}
tips:泛型是数据类型的一部分,我们将类名与泛型合并一起看做数据类型。
我们在集合中会大量使用到泛型,这里来完整地学习泛型知识。
泛型,用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数进行传递。
定义格式:
修饰符 class 类名<代表泛型的变量> { }
例如,API中的ArrayList集合:
泛型在定义的时候不具体,使用的时候才变得具体。在使用的时候确定泛型的具体数据类型。
class ArrayList<E>{
public boolean add(E e){ }
public E get(int index){ }
....
}
使用泛型: 即什么时候确定泛型。
在创建对象的时候确定泛型
例如,ArrayList
此时,变量E的值就是String类型,那么我们的类型就可以理解为:
class ArrayList<String>{
public boolean add(String e){ }
public String get(int index){ }
...
}
再例如,ArrayList
此时,变量E的值就是Integer类型,那么我们的类型就可以理解为:
class ArrayList<Integer> {
public boolean add(Integer e) { }
public Integer get(int index) { }
...
}
定义格式:
修饰符 <代表泛型的变量> 返回值类型 方法名(参数){ }
例如,
public class MyGenericMethod {
public <MVP> void show(MVP mvp) {
System.out.println(mvp.getClass());
}
public <MVP> MVP show2(MVP mvp) {
return mvp;
}
}
调用方法时,确定泛型的类型
public class GenericMethodDemo {
public static void main(String[] args) {
// 创建对象
MyGenericMethod mm = new MyGenericMethod();
// 演示看方法提示
mm.show("aaa");
mm.show(123);
mm.show(12.45);
}
}
定义格式:
修饰符 interface接口名<代表泛型的变量> { }
例如,
public interface MyGenericInterface<E>{
public abstract void add(E e);
public abstract E getE();
}
使用格式:
1、定义类时确定泛型的类型
例如
public class MyImp1 implements MyGenericInterface<String> {
@Override
public void add(String e) {
// 省略...
}
@Override
public String getE() {
return null;
}
}
此时,泛型E的值就是String类型。
2、始终不确定泛型的类型,直到创建对象时,确定泛型的类型
例如
public class MyImp2<E> implements MyGenericInterface<E> {
@Override
public void add(E e) {
// 省略...
}
@Override
public E getE() {
return null;
}
}
确定泛型:
/*
* 使用
*/
public class GenericInterface {
public static void main(String[] args) {
MyImp2<String> my = new MyImp2<String>();
my.add("aa");
}
}
当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。
通配符:?
可以用在使用泛型的时候代表一切类型。
E,T,K,V是在定义泛型的时候使用代表一切类型。
泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符。
此时只能接受数据,不能往该集合中存储数据。
举个例子大家理解使用即可:
public static void main(String[] args) {
Collection<Intger> list1 = new ArrayList<Integer>();
getElement(list1);
Collection<String> list2 = new ArrayList<String>();
getElement(list2);
}
public static void getElement(Collection<?> coll){}
// ?代表可以接收任意类型
泛型不存在继承关系 Collection<Object> list = new ArrayList<String>();这种是错误的
之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在JAVA的泛型中可以指定一个泛型的上限和下限。
泛型的上限:
类型名称 对象名称
只能接收该类型及其子类
泛型的下限:
类型名称 对象名称
只能接收该类型及其父类型
比如:现已知Object类,String 类,Number类,Integer类,其中Number是Integer的父类
public static void main(String[] args) {
Collection<Integer> list1 = new ArrayList<Integer>();
Collection<String> list2 = new ArrayList<String>();
Collection<Number> list3 = new ArrayList<Number>();
Collection<Object> list4 = new ArrayList<Object>();
getElement(list1);
getElement(list2);//报错
getElement(list3);
getElement(list4);//报错
getElement2(list1);//报错
getElement2(list2);//报错
getElement2(list3);
getElement2(list4);
}
// 泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
public static void getElement1(Collection<? extends Number> coll){}
// 泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类
public static void getElement2(Collection<? super Number> coll){}