1.设置可变参数的函数:
public static int add(int x,int...args){
int sum = 0;
for(int arg : args){//增强的for循环
sum += arg;
}
return sum;
}
2.基本数据类型的自动装箱和拆箱,
基本数据类型的自动装箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0开始提供的功能。
一般我们要创建一个类的对象的时候,我们会这样:Class a = new Class(parameter);
当我们创建一个Integer对象时,却可以这样:Integer i = 100; (注意:不是 int i = 100; )
实际上,执行上面那句代码的时候,系统为我们执行了:Integer i = new Integer(100); 此即基本数据类型的自动装箱功能。
自动装箱时对于值从–128到127之间的值,它们被装箱为Integer对象后,会存在内存中被重用
这里面其实使用了一个设计模式:享元模式,具体请参看这篇文章:
3.枚举
特点:构造函数私有化,所以如果有一个枚举,可以作为特殊的单例
public enum TranfficLamp{
RED (30){
@Override
public TranfficLamp nextLamp() {
return GREEN;
}
},GREEN(45) {
@Override
public TranfficLamp nextLamp() {
// TODO Auto-generated method stub
return YELLOW;
}
},YELLOW(5) {
@Override
public TranfficLamp nextLamp() {
// TODO Auto-generated method stub
return RED;
}
};
public abstract TranfficLamp nextLamp();
private int time;
private TranfficLamp(int time){
this.time = time;
}
}
使用方式:
TranfficLamp t1 = TranfficLamp.RED;
TranfficLamp t2 = t1.nextLamp();
4.Java反射机制:
反射就是把Java类中的各个成分映射成相应的Java类;
Class(字节码对象)的3中获取方式:
Objexct.getClass();
类名.Class;
Class.forName();
public boolean isPrimitive()判定指定的 Class
对象是否表示一个基本类型。
public boolean isArray()判定此 Class
对象是否表示一个数组类。
4.1构造函数的反射
Class cl = Person.class;
Constructor cst = cl.getConstructor(String.class,String.class,int.class);
Person p = (Person) cst.newInstance("张三","boy",15);//产生新对象
System.out.println(p.toString());
关于Person类,定义如下:
public class Person {
private String name;
private String sex;
private int age;
public Person(String name, String sex,int age) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
public void setPerson(String name, String sex,int age) {
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setages(int[] ages){
this.age = ages[0];
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";
}
}
4.2 成员变量的反射
Person person = new Person("张三","sdf",15);
Field field_age = Person.class.getDeclaredField("age");
field_age.setAccessible(true);//暴力反射
System.out.println(field_age.get(person));
getDeclaredField
public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException
-
返回一个
Field
对象,该对象反映此Class
对象所表示的类或接口的指定已声明字段。name
参数是一个String
,它指定所需字段的简称。注意,此方法不反映数组类的length
字段。
4.3 成员方法的反射
Person person = new Person("bask", "boy",15);
Method methodSetName = Person.class.getMethod("setName",String.class);
methodSetName.invoke(person, "hello");
System.out.println(person.toString());
如果是静态方法,Method.invoke(null,参数);
如果该函数不带参数呢?
Method methodGetName = Person.class.getMethod("getName", null);
System.out.println(methodGetName.invoke(person, null));
如果函数是多个参数
Class[] cls= new Class[]{String.class,String.class,int.class};
Method methodSet = Person.class.getMethod("setPerson", cls);
Object[] objs = new Object[]{new String("daoqin"),new String("bigboy"),23};
methodSet.invoke(person, objs);
System.out.println(person.toString());
如果传递的参数是一个数组
Method setagesMethod = Person.class.getMethod("setages", int[].class);
setagesMethod.invoke(person, (Object)new int[]{128,18,15,16,17});
System.out.println(person.toString());
注意:
invoke
public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
-
对带有指定参数的指定对象调用由此
Method
对象表示的底层方法。个别参数被自动解包,以便与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换。如果底层方法是静态的,那么可以忽略指定的
obj
参数。该参数可以为 null。如果底层方法所需的形参数为 0,则所提供的
args
数组长度可以为 0 或 null。
setagesMethod.invoke(person, (Object)new int[]{128,18,15,16,17});
4.4数组对象的反射
private static void printObject(Object object) {
// TODO Auto-generated method stub
Class cl = object.getClass();
if(cl.isArray()){
int len = Array.getLength(object);
for (int i = 0; i < len; i++) {
System.out.println(Array.get(object, i));
}
}
else {
System.out.println(object);
}
}
调用方式:
int[] a1 = new int[]{1,2,3};
String[] a2 = new String[]{"abc","bcd"};
printObject(a1);
printObject(a2);
最后看下面这个代码:
int[] a1 = new int[4];
int [][] a2 = new int[2][3];
Object object = a1;//正确 int[] 是一个Object对象
Object[] objects = a2;//正确 理由同上
Object[] objects2 = a1;//错误,int不是Objext对象