2018/08/03 07:29
Java部分新特性:
- JDK 1.2 : 推出了轻量级的界面包Swing
- JDK 1.5 : 推出新程序结构的设计思想
- JDK 1.8 : Lambda表达式,接口定义加强
可变参数
// 早期是利用数组传参,现在要求是任意多个数组的传参
从JDK1.5之后就追加了可变参数的概念
public [static] [final] 返回值 方法名称([参数类型 参数名称][参数类型 ... 参数名称]){}
这个"..."实际上表示一个数组的结构。
注意点:如果要传递多类参数,可变参数一定要放在最后,并且只能设置一个可变参数
foreach循环(增强型for循环)
for(数据类型 临时变量 : 数组(集合)) {
// 循环次数自动为数组长度,而且每一次循环都会顺序取出数组中的一个元素赋值给临时变量
}
即在for循环里面无须使用索引来取数据
通过此方式可以很好的避免数组越界的问题,但是这种数组的操作只适合简单输出模式。
静态导入
从JDK1.5之后,如果类中方法全是static方法,则可以直接把这个类的方法导入进来,这样就好比像在主类中定义的方法那样,可以被主方法直接调用。
例:
package com.jason.java.test;
import static com.jason.java.util.Myath.*; //静态类导入
public class TestDemo {
public static void main(String[] args) {
System.out.println(add(10, 20));
System.out.println(sub(10, 20));
}
}
泛型
从JDK1.5以后引入了三大常用新特性:泛型,枚举(enum),注解(Annotation)。其中在JDK1.5中泛型是一件非常重要的技术实现,可以帮助我们解决程序的参数转换问题。
1.单参数泛型
class MaClass<T> {
T value;
}
尖括号 <> 中的 T 被称作是类型参数,用于指代任何类型。实际上这个T你可以任意写,但出于规范的目的,Java
还是建议我们用单个大写字母来代表类型参数。
```
2.多参数泛型
```
class MyClass<T, E> {
T value1;
E value2;
}
常见的如:
- T 代表一般的任何类
- E 代表Element的意思,或者Exception异常的意思
- K代表Key的意思
- V代表Value的意思,通常与K一起配合使用
- S代表Subtypede的意思
注意泛型只能接收类,所有的基本数据类型必须使用包装类
3.使用时
public class Test {
public static void main(String[] args) {
MyClass<String, Integer> myClass1 = new MyClass<String, Integer>();
}
}
泛型方法
例:
class MyClass {
public <T> void testMethod(T t) {
System.out.println(t);
}
public <T> T testMethod2(T t) {
return t;
}
}
泛型方法与泛型类稍有不同的地方是,类型参数也就是尖括号那一部分是写在返回值前面的。 中的 T 被称为类型参数,而方法中的 T 被称为参数化类型,它不是运行时真正的参数。
泛型方法与泛型类共存
class MyClass<T> {
public void testMethod1(T t) {
System.out.println(t);
}
public <T> testMethod2(T t) {
System.out.println(t);
}
}
上面代码中:testMethod1 是泛型类中的普通方法,而testMethod2 是一个泛型方法。
泛型方法始终以自己定义的类型参数为准,
因此为了不混淆,两者的参数类型最好不要同名。
通配符
在程序中追加了泛型的定义之后,避免了ClassCastException的问题,但是又会产生新的情况:参数的统一问题。
class Message<T> {
private T message;
public T getMessage() {
return message;
}
public void setMessage(T message) {
this.message = message;
}
}
public class TestDemo {
public static void main(String[] args) {
// 这一组是没有任何问题
Message<String> message1 = new Message();
message1.setMessage("hello world");
fun(message1);
//
Message<Integer> message2 = new Message();
message2.setMessage(99);
fun(message2); // 这里会出现错误
}
pbulic static void fun(Message<String> temp) { // 这里只能接收实际类型为String的,
System.out.println(temp.getMessage());
}
}
总结:争对以上情况我们需要的是,可以接收所有的泛型类型,但是又不能够让用户随意修改,这时候就需要用到通配符"??"来处理。
例:使用通配符
public class TestDemo {
public static void main(String[] args) {
Message<Integer> message = new Message();
message.setMessage(55);
fun(message);
}
// 此时使用通配符"?"描述的是他可以接收任意类型,但是由于不确定类型,所以无法修改。
public static void fun(Message<?> temp) {
System.out.println(temp.getMessage());
}
}
在”?”通配符的基础上又产生了两个子通配符
- ? extends 类:设置泛型上限
- ? super 类:设置泛型下限
例:
? extends Number, 表示只能够设置Number或其子类,例如: Integer, Double等
? super String, 表示只能够设置String及其父类Object.
注意:上线可以用在声明,不能修改;而下线只能用在方法参数,可以修改内容
泛型接口
interface IMessage<T> {
public void print(T t);
}
其子类的实现有两种:
package com.jason.java.test;
interface IMessage<T> {
public void print(T t);
}
// 子类在定义时继续使用泛型
class MessageImpl1<T> implements IMessage<T> {
@Override
public void print(T t) {
System.out.println(t);
}
}
// 子类在实现接口时明确给出具体类型
class MessageImpl2 implements IMessage<String> {
@Override
public void print(String t) {
System.out.pirntln(t);
}
}
泛型擦出
泛型信息只存在于代码编译阶段,在进入JVM之前,与泛型相关的信息会被擦出,专业术语叫做泛型擦出。
在泛型类被类型擦除的时候,之前泛型类中的类型参数部分如果没有指定上限,如 则会被转译成普通的
Object 类型,如果指定了上限如 则类型参数就被替换成类型上限。