一、JDK1.5 中简单的新特性
静态导入;例如:
package com.staticimport.demo;
import static java.lang.Math.max;
import static java.lang.Math.abs;
public class StaticImport {
/**
* @param args
* 静态导包。
*/
public static void main(String[] args) {
//使用了静态导包之后可以直接调用方法
System.out.println(max(26.3,32.5));
System.out.println(abs(3-10));
}
}
可变参数
可变参数特点:
只能出现在参数列表最后
“… ”位于变量类型和变量名之间,前后有无空格都可以
调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数
例:
package com.enable.demo;
public class EnableParameters {
public static void main(String[] args) {
System.out.println(enableChange(10, 2,3));
System.out.println(enableChange(10, 2,3,5));
System.out.println(enableChange(10, 2,3,5,10));
}
public static int enableChange(int x ,int... args){
int count = 0 ;
for (int i = 0; i < args.length; i++) {
count += args[i];
}
return count ;
}
}
语法:for(type(变量) : 变量名)
自动装箱与拆箱
享元模式:有很多个相同属性的小的对象封装成一个对象,而其他不同的属性作为方法的参数,这些叫外部状态,形同的属性称之为内部状态。
例如:
Integer iObj = 36 ;
Integer iObj1 = 36 ;
System.out.println(iObj == iObj1); //true
Integer iObj2 = 136 ;
Integer iObj3 = 136 ;
System.out.println(iOb2 == iObj3); //false
二、java5的枚举
2、枚举的实现
public class EmumDemo {
public static void main(String[] args) {
/*
WeekDay1 weekDay = WeekDay1.MON;
System.out.println(weekDay);
System.out.println(weekDay.nextDay());
*/
WeekDay weekDay = WeekDay.THI ;
System.out.println(weekDay);
System.out.println(weekDay.name());
System.out.println(weekDay.ordinal());
System.out.println(weekDay.valueOf("SUN").toString());
}
//定义一个枚举类
public enum WeekDay{
SUN,MON,TUE,WED,THI,SAT;
}
}
3、 为枚举定义构造方法(带参数的构造方法)
定义的所有方法都必须在元素列表之后 ,且元素列表必须有分好”;”即结束符号。
如果枚举中只有一个元素可以用,那么这个枚举可以写成一个单例。
下面代码是一个带有有参构造方法和抽象方法的枚举类。描述了一组交通灯。
public enum TrifficLamp {
RED(20) {
// 覆写类中抽象方法
public TrifficLamp netLamp() {
return BLUE;
}
},
BLUE(45) {
public TrifficLamp netLamp() {
return YELLOW;
}
},
YELLOW(5) {
public TrifficLamp netLamp() {
return RED;
}
};
public abstract TrifficLamp netLamp();
private int time;
private TrifficLamp(int time) {
this.time = time;
}
}
三、反射的深入讲解
1、反射的基石—>Class类
Java程序中的各个类属于同一类事物,描述这类事物的java类名就是Class
Person->人
Java类->Class
一个类被被加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不同的,所以他们在内存中的内容是不同的,这一个个的空间可分别用一个个的对象来表示,这些对象显然具有相同的类型,这个类型是什么呢?
如何的到各个字节码对应的实例对象(Class类型)
(1) 类名.class,例如,System.calss;
(2) 对象.getClass(),例如,new Date().getClass();
(3) Class.forName(“类名”)例如”Class.forName(“java.util.Date”);
例:用上面的三种方式获取对象的clss字节码对象
public class GetClassFile {
public static void main(String[] args)throws Exception {
String str = "abc";
Class clazz1 = str.getClass();
Class clazz2 = String.class;
Class clazz3 = Class.forName("java.lang.String");
System.out.println(clazz1 == clazz2);
System.out.println(clazz1 == clazz3);
//isPrimitive()判断是否是一个基本类型的字节码
System.out.println(clazz1.isPrimitive());
}
}
2、反射的概念
反射就是把一个java类中的各个成分(如:成员,方法等)映射成相应的java类。
例:反射一个类中的构造方法,并用其创建并实例化一个新对象
import java.lang.reflect.Constructor;
public class ReflectConstructorDemo {
public static void main(String[] args) throws Exception {
String content = "StringBuffer为构造器参数的String对象";
// 获取String字节码对象
Class clazz = Class.forName("java.lang.String");
// 获取String的带参构造方法,参数类型是:StringBuffer
Constructor<String> constructor =
clazz.getConstructor(StringBuffer.class);
// 创建String对象,使用构造器参数为StringBuffer
String str =
constructor.newInstance(new StringBuffer(content));
System.out.println(str);
}
}
例:反射一个类中成员,并打印其值
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class ReflectConstructorDemo {
public static void main(String[] args) throws Exception {
ReflectPoint rp = new ReflectPoint(20, 10);
//获取ReflectPoint字节码对象
Class clazz1 = Class.forName("com.reflect.demo.ReflectPoint");
//获取成员y
Field fieldY = clazz1.getField("y");
System.out.println(fieldY.get(rp));
//由于x的访问权限修饰符为private,所以要使用强制反射
Field fieldX = clazz1.getDeclaredField("x");
//强制访问
fieldX.setAccessible(true);
System.out.println(fieldX.get(rp));
}
}
ReflectPoint.java类略。
例:反射成员的综合应用,修改成员的值
private static void changeValue(Object rp)throws Exception {
//获取字节码对象的所有成员,存入到数组fields
Field[] fields = rp.getClass().getFields();
//迭代出每一个成员
for(Field field : fields){
//如果成员的类型为String,执行替换操作
if(field.getType() ==
Class.forName("java.lang.String")){
String oldValue = (String) field.get(rp);
String newValue = oldValue.replace('b', 'c');
field.set(rp, newValue);
}
}
}
执行上述代码时候,需要在ReflectPoint中加入一个String类型的成员,成员名您随意。
例:通过反射调用类中的成员方法
<pre name="code" class="java">public static void reflectMethod(String str1)throws Exception {
//获取Str1的字节码对象,并获取方法,并赋值给methodCharAt
Method methodCharAt =
str1.getClass().getMethod("charAt", int.class);
//调用str1对象的charAt方法,传入参数2;等价于str1.charAt(2)
System.out.println(methodCharAt.invoke(str1, 2));
//按照jdk1.4的语法调用str1对象的charAt方法,传入参数1;等价于str1.charAt(1)
System.out.println(
methodCharAt.invoke(str1, new Object[]{1}));
}
上述代码在调用的时候需要传入一个String类型的对象,值随意。