JDK1.5新特性:
1.自动装箱与拆箱
自动装箱:指开发人员可以把一个基本数据类型直接赋给对应的包装类。
自动拆箱:指开发人员可以把一个包装类对象直接赋给对应的基本数据类型
public static void main(String[] args){
//自动装箱
Integer i=10;
//自动拆箱
int m = i;
}
public void test1(){
//手动装箱
Integer m=new Integer(10);
//手动拆箱
int a=m.intValue();
}
2.枚举
一些方法在运行时,它需要的数据不能是任意的,而必须是一定范围内的值,此类问题在JDK5以前采用自定义带有枚举功能的类解决,Java5以后可以直接使用枚举予以解决。
枚举原型
class Color{
private Color() {}
public static final Color Red = new Color();
public static final Color Blue = new Color();
public static final Color Gry = new Color();
public static final Color Black = new Color();
public static final Color Yellow = new Color();
}
枚举
enum MyColor{
RED("red"){
public void print1(){}
}, GREEN("green"){
public void print1(){}
};
//构造方法 必须为私有
private MyColor(String name){}
//当枚举类 写了抽象方法以后 需要在每个实例中实现这个方法
public abstract void print1();
}
3.静态导入,如:import static java.lang.System.out
静态导入用于简化程序对类静态属性和方法的调用。
import static java.lang.System.out;
import static java.util.Arrays.sort;
public class Test{
public static void main(String[] args){
out.println("hello");// 不用静态导入 System.out.println("hellow");
int[] arr1={1,2,3,4};
sort(arr1);
out.println(Arrays.toString(arr1));
}
}
4.可变参数(Varargs)
不使用可变参数 需要使用重载
public int sum(int num1,int num2 ,int num3) { // 3个参数
int total = num1 + num2 + num3;
System.out.println(total);
return total;
}
public int sum(int num1) { // 1个参数
int total = num1;
System.out.println(total);
return total;
}
public int sum(int num1,int num2 ) { // 2个参数
int total = num1 + num2;
System.out.println(total);
return total;
}
使用可变参数
1可变参数写在参数列表后面 public void other(int ...nums, int x) 这样写是错误的!
2参数列表中只能有一个可变参数
3可变参数只能存在参数列表中 不能在其他地方定义
public int sum(int ...nums) { // 可变参数,我们可以将其看成是一个数组
int total = 0;
for (int i: nums) {
total += i;
}
System.out.println(total);
return total;
}
5.内省(Introspector),主要用于操作JavaBean中的属性,通过getXxx/setXxx。一般的做法是通过类Introspector来获取某个对象的BeanInfo信息,然后通过BeanInfo来获取属性的描述器(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后我们就可以通过反射机制来调用这些方法。
6.泛型(Generic)(包括通配类型/边界类型等)
JDK5以前,对象保存到集合中就会失去其特性,取出时通常要程序员手工进行类型的强制转换,这样不可避免就会引发程序的一些安全性问题。
ArrayList list = new ArrayList();
list.add("abc");
Integer num = (Integer) list.get(0); // 运行时会出错,但编码时发现不了
JDK5中的泛型允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定性(尤其在大型程序中更为突出)。
泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛型的java程序后,生成的class文件中将不再带有泛型信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”
使用泛型
使用泛型时,泛型类型须为引用类型,不能是基本数据类型;
ArrayList<String> list = new ArrayList();
ArrayList list = new ArrayList<String>(); 是正确的,但是在添加数据时编译器没有对类型进行校验。
泛型方法 (T只能表示 ByteShort Integer Long Float Double Character Boolean )
public static <T> void mySwap(T[] arr, int a, int b){
T temp= arr[a];
arr[a]= arr[b];
arr[b]= temp;
}
泛型类
public class Test<T>{
T aa;
public void test1(T bb){}
// 类上面的泛型不能在静态方法中使用
public static <A> void test2(A cc){}
}
7.增强for循环
普通for循环
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
for (int i=0;i<list.size();i++) {
Integer a=list.get(i);
System.out.println(a);
}
迭代器
List<String> list=new ArrayList<String>();
list.add("111");
list.add("222");
list.add("333");
Iterator<String> it=list.iterator();
while(it.hasNext()){
System.out.println(it.next));
}
增强for
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
for (Object obj : list) {
int i = (Integer) obj;
System.out.println(i);
}
8. 反射
一个类有多个组成部分,例如:成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。
Java中有一个Class类用于代表某一个类的字节码。
三种得到class对象的方式:
- 类名.class,如Person.class;
- 对象.getClass(),如new Person().getClass()。
- Class.forName("className") forName方法用于加载某个类的字节码到内存中,并使用class对象进行封装。
public static void main(String[] args) throws ClassNotFoundException {
Class class1=Person.class;
Class class2=new Person().getClass();
Class class3=Class.forName("cn.test.reflectText.Person");
}
属性类 Field 构造器类 Constructor 方法类 Method
反射操作
package cn.test.reflectText;
public class Person {
private String name;
private String id;
//构造方法
public Person(){}
public Person(String name, String id){
this.name=name;
this.id=id;
}
//普通方法
public String getName(){
return name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
package cn.test.reflectText;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import org.junit.Test;
public class TestClass {
public static void main(String[] args) throws ClassNotFoundException {
Class c1=Person.class;
Class c2=new Person().getClass();
Class c3=Class.forName("cn.test.reflectText.Person");
}
//操作name属性
@Test
public void test(){
try{
//得到Class类
Class c2=Class.forName("cn.test.reflectText.Person");
//得到name属性
//c2.getDeclaredFields();//表示得到所有的属性
Field f1=c2.getDeclaredField("name");
//得到Person类的实例
Person p11=(Person) c2.newInstance();
//设置可以操作私有属性
f1.setAccessible(true);
//设置name值
f1.set(p11, "wangwu");//相当于 在p.name ="wangwu"
System.out.println(f1.get(p11)); //相当于p.name
}catch(Exception e){
e.printStackTrace();
}
}
//操作有参数的构造方法
@Test
public void test2() throws Exception{
//得到Class
Class c1=Class.forName("cn.test.reflectText.Person");
//使用有参数的构造方法
// c1.getConstructors() //获得所有的构造方法
//类型使用class形式传递
Constructor cs=c1.getConstructor(String.class,String.class);
//通过有参数的构造方法设置值
//通过有参数的构造方法创建Person实例
Person p1=(Person)cs.newInstance("lisi","100");
System.out.println(p1.getId()+" "+p1.getName());
}
//操作无参数的构造方法
@Test
public void test1() throws Exception{
//得到Class
Class c3=Class.forName("cn.test.reflectText.Person");
//得到Person类的实例
Person p=(Person) c3.newInstance();
//设置值
p.setName("zhangsan");
System.out.println(p.getName());
}
}