浮点型数据:基本数据类型 -> 包装为Double类对象 ->自动向上转型为Object;
字符串型数据:String 类对象 -> 自动向上转型为Object;
[](()2.泛型
=================================================================
如果想要避免项目之中出现"ClassCastException"最好的做法是可以直接回避掉对象的强制转换,所以在JDK1.5之后提供有泛型的技术,而泛型的本质在于,类中的属性或方法的参数与返回值的类型可以由对象实例化的时候动态决定。那么此时就需要在类定义的时候明确的定义占位符(泛型标记)。
例如:定义一个Point类
class Point <T>{
private T x;
private T y;
public void setX(T x){
this.x=x;
}
public void setY(T y){
this.y=y;
}
public T getX(){
return this.x;
}
public T getY(){
return this.y;
}
}
public class test {
public static void main(String[] args) {
Point point = new Point();
point.setX(10);
point.setY(20);
int x = (Integer) point.getX();
int y = (Integer) point.getY();
System.out.println("x坐标: " + x + ",y坐标:" + y);
}
}
这里Point类中的x与y属性的数据类型并不确定,而是由外部来决定。
提示一下:关于默认的泛型类型
由于泛型是属于JDK1.5之后的产物,但是在这之前已经有不少内置的程序类或者是接口已经广泛的应用在项目开发之中,于是为了保证这些类或接口追加了泛型之后,原始的程序类依然可以使用,所以如果不设置泛型类型时,自动将Object作为类型,以保证程序的正常执行,但是在编译的过程之中会出现警告信息。
例如:
class Point<T> {
private T x;
private T y;
public void setX(T x) {
this.x = x;
}
public void setY(T y) {
this.y = y;
}
public T getX() {
return this.x;
}
public T getY() {
return this.y;
}
}
public class test {
public static void main(String[] args) {
Point<Integer> point = new Point<Integer>();
point.setX(10);
point.setY(20);
int x = point.getX();
int y = point.getY();
System.out.println("x坐标: " + x + ",y坐标:" + y);
}
}
现在的程序代码之中,由于Point类设置的泛型类型为Integer,这样所有的对应此泛型的属性、变量、方法返回值,就将全部替换为Integer,但只局限于此对象当中。
泛型的使用注意点:
1.泛型之中只允许设置引用类型,如果现在要操作基本类型必须使用包装类;
例如:将Integer换成int就不可以执行了。
2.从JDK1.7开始,泛型对象实例化可以简化为:
"Point<Integer> point = new point();"后面<>可以省略!!
[](()3.泛型通配符
====================================================================
虽然泛型帮助开发者解决了一系列的对象的强制转换所带来的安全隐患,但是从另外一个角度来讲,泛型也带来了一些新的问题:引用传递处理
例如:
class Message<T>{
private T content;
public void setContent(T content){
this.content = content;
}
public T getContent(T content){
return this.content;
}
}
public class test {
public static void main(String[] args) {
Message<String> msg = new Message<String>();
msg.setContent("WWW.BAIDU.COM");
fun(msg);
}
public static void fun(Message<String> tmp){
System.out.println(tmp.getContent());
}
}
这里问题的关键在于fun()的函数引用,如果真的去使用泛型不可能只是一种类型,也就是说fun()方法按理应该可以接受任意种泛型类型的Message对象。
如果这里函数引用不设置泛型:
例如:
class Message<T>{
private T content;
public void setContent(T content){
this.content = content;
}
public T getContent(T content){
return this.content;
}
}
public class test {
public static void main(String[] args) {
Message<Integer> msg1 = new Message<Integer>();
Message<String> msg2 = new Message<String>();
msg1.setContent(110);
fun(msg1);//引用传递
msg2.setContent("www.baidu.com");
fun(msg2);
}
public static void fun(Message tmp){
tmp.setContent(1.1);
System.out.println(tmp.getContent());
}
}
这里的fun函数没有设置泛型,反而出现了更大的问题,在函数里面写入tmp.setContent(1.1);发现上面的结果全都变成了1.1。
这个时候发现如果不设置泛型,那么在方法之中就有可能对你的数据进行修改,所以此时需要找一种方案:可以接受所有的泛型类型,并且不能够修改里面的数据(但是允许获取),那么就需要通配符"?"来解决。
例如:
class Message<T> {
private T content;
public void setContent(T content) {
this.content = content;
}
public T getContent(T content) {
return this.content;
}
}
public class test {
public static void main(String[] args) {
Message<Integer> msg1 = new Message<Integer>();
Message<String> msg2 = new Message<String>();
msg1.setContent(110);
fun(msg1);//引用传递
msg2.setContent("www.baidu.com");
fun(msg2);
}
public static void fun(Message<?> tmp) {
System.out.println(tmp.getContent());
}
}
此时在fun()方法里面由于采用了Message结合统配符的处理所以可以接受所有的类型,并且不允许修改,只允许获取数据。
提示一下:
" ? "在通配符的基础上还有两个类型的通配符:
1." ? extends 类 " :设置泛型的上限
例如:
" ? extends Number "表示该泛型类型只允许设置Number或Number的
子类。
- " ? super 类 " :设置泛型的下限
例如:
" ? super String " 表示只能够使用String或其父类。
[](()3.泛型接口
===================================================================
泛型除了可以在类上定义之外也可以直接在接口之中进行使用。
实现方式一:在子类之中继续设置泛型定义
例如:
interface IMessage<T> {
public String echo(T t);
}
class MessageImpl<S> implements IMessage<S> {
public String echo(S t) {
return "ECHO " + t;
}
}
public class test {
public static void main(String[] args) {
IMessage<String> msg = new MessageImpl<String>();
System.out.println(msg.echo("www.baidu.com"));
}
}
实现方式二:在子类实现父接口的时候直接定义出具体泛型类型