枚举示例:
package li.dao.fu.test.enums;
/*
* 枚举是一种特殊形式的java类
* 枚举中声明的每一个枚举值代表枚举类的一个实例对象
* 与java普通类一样,在声明枚举类时,也可以声明属性,方法和构造函数,但枚举的构造函数必须为私有的
* 枚举也可以实现接口,或继承抽象类
* 若枚举中只有一个值可以当成单例设计模式
* */
public enum EnumTest {
A(90,100){
//实现抽象方法
public String getLevel(){
return "优秀";
}
},
B(80,90){
public String getLevel(){
return "良好";
}
},
C(70,80){
public String getLevel(){
return "一般";
}
},
D(60,70){
public String getLevel(){
return "及格";
}
},
E(0,60){
public String getLevel(){
return "不及格";
}
};
private int minScore;
private int maxScore;
//枚举的构造函数必须是私有的,这是因为它不能被外界所实例化,只能是固定的那几个实例,不能改变
private EnumTest(int minScore,int maxScore){
this.minScore=minScore;
this.maxScore=maxScore;
}
public int getMin(){
return this.minScore;
}
public int getMax(){
return this.maxScore;
}
//枚举中定义的抽象方法,必须在每个实例中实现这个方法
public abstract String getLevel();
}
package li.dao.fu.test.enums;
public class Test {
public static void main(String[] args) {
System.out.println("Grade Level:");
String[] chs={"A","B","C","D","E"};
for(int i=0;i<chs.length;i++){
//根据指定的字符串返回相应的枚举实例
EnumTest TEMP=EnumTest.valueOf(chs[i]);
//name:返回相应枚举实例的名字
System.out.println(TEMP.name()+":"+TEMP.getLevel());
System.out.println(TEMP.getMin()+"-"+TEMP.getMax());
}
//枚举类有一个隐含的方法values,返回所有枚举实例,但API没有写出这个方法
EnumTest[] enums=EnumTest.values();
for(int i=0;i<enums.length;i++){
if(enums[i].name()=="D"){
System.out.println(enums[i].getMin()+"-"+enums[i].getMax());
}
}
//返回枚举实例对应的索引
int index=EnumTest.C.ordinal();
System.out.println("index:"+index);
}
}
反射示例:
package li.dao.fu.test.reflect;
public class Person {
public String name;
public int age;
public Person(){
System.out.println("no parameter");
}
private Person(String name,int age){
this.name=name;
this.age=age;
}
public void show(String message){
System.out.println("message:"+message);
System.out.println("name:"+this.name+" age:"+this.age);
}
private void out(){
System.out.println("name:"+this.name+" age:"+this.age);
}
public static void print(String message){
System.out.println("message:"+message);
}
public static int getMax(int[] nums){
int max=nums[0];
for(int i=1;i<nums.length;i++){
if(nums[i]>max)
max=nums[i];
}
return max;
}
public static String getMaxLength(String[] strs){
int max=0;
for(int i=1;i<strs.length;i++){
if(strs[i].length()>strs[max].length())
max=i;
}
return strs[max];
}
}
package li.dao.fu.test.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectTest {
/*
* 利用反射创建对象的三个步骤:
* 1.获得类的Class文件
* 三种方式可获得class文件:
* a.利用静态方法:Class.forName(类名),类名必须是类的全名包括包名
* b.类名.Class()
* c.对象名.getClass()
* 2,利用Class文件获取构造函数
* 二种方式:
* a.getConstructor(Class...):获取类的公有的构造函数,无法获取非public的构造函数
* b.getDeclaredConstructor(Class...):获取类的所有构造函数,只要类中声明了就可获取
* 3.利用构造函数实例化
* newInstance(参数);注意:如果构造函数是通过getDeclaredConstructor()方法获得的,那么
* 在用这个构造函数创建对象时,要先设定它的访问权限为true即setAccessible(true);暴力访问
*
* 为了方便利用反射来创建对象,API还提供了一个newInstance()方法来创建对象,可以直接通过Class文件来
* 创建对象,类Class.newInstance();但这个种方式只能创建无参的对象,并且这个 类的无参构造函数必须是公有的
*
*
* 利用反射调用方法
* 方法步骤和利用反射创建对象步骤相似
* 注意点:
* a.在获取方法或在调用方法时,如果方法无参数可以不写或者写null;
* b.在调用静态的方法时,调用对象可以写null;
* c.在调用方法即调用invoke方法时,要注意如果给方法传递的是非基本数据类型的数组时,要将这个数组转换
* 成Object对象或打包成一个新的数组;这是因为在JDK1.4中invoke(Object obj,Object[] objs)
* 方法中的objs参数是一个Object数组,invoke方法会将这个数组拆开然后将值传递给方法,所以如果要调用
* 的方法需要的是一个数组时就无法传递进去,所以如果要传递一个数组给方法时,必须先要将这个数组打包成一个新的数组
* 这样当invoke拆开这个数组时,里面还是个数组,就可以将数组传递过去了,当然也可以将这个数组转换成一个对象,
* invoke方法看到传递的是一个对象时就不会拆开这个对象了
*
*
*
* */
public static void main(String[] args) throws Exception {
//获取Class文件
Class<?> claxx=Class.forName("li.dao.fu.test.reflect.Person");
//利用class文件获取所需的构造函数
//Constructor<?> con=claxx.getConstructor(null);
//创建对象
//Person p=(Person) con.newInstance(null);
//获取非公有的构造函数
Constructor<?> con1=claxx.getDeclaredConstructor(String.class,int.class);
//将访问权限高为true,即暴力反射
con1.setAccessible(true);
//创建对象
Person p1=(Person) con1.newInstance("lidaofu",24);
//获取类的所有公有方法
Method[] methods=claxx.getMethods();
for(Method method:methods){
System.out.println(method.getName());
}
//访问私有无参数的方法
//暴力访问类中的私有方法,getDeclaredMethod方法的第一个参数为要获取的方法名,第二个为方法的参数类型class对象,如果为无参函数则为null或者不写
Method method=claxx.getDeclaredMethod("out");
//将访问权限设为true
method.setAccessible(true);
//调用方法,invoke方法的第一个参数为调用该方法的对象,第二个是为该方法指定的参数,如果是无参函数可以不写或写null
method.invoke(p1); //method.invoke(p1,null);
//访问公有有参数的方法
Method method2=claxx.getMethod("show", String.class);
//指明调用该方法的对象和为对象的赋值
method2.invoke(p1, "调用有参数的方法");
//调用静态有参数的方法
Method method3=claxx.getMethod("print",String.class);
//调用静态方法时,可以不指定调用的对象,写null即可
method3.invoke(null, "静态方法调用");
//调用静态参数为基本数据类型的数组的方法
Method method4=claxx.getMethod("getMax",int[].class);
//这里传递的数组是基本数据类型的数组,可以不用转换成一个对象或者打包成一个新的数组
Integer max=(Integer)method4.invoke(null, new int[]{2,6,1,7,5,9});
System.out.println("max="+max);
//调用静态参数为非基本数据类型的数组的方法
Method method5=claxx.getMethod("getMaxLength", String[].class);
//这里在传递非基本数据类型的数组参数时,要注意应该将这个参数数组打包成一个新数组或或者转换成一个Object对象传递过去,这是为了兼容JDK1.4,不然后出现异常
String maxLength=(String)method5.invoke(null,new Object[]{new String[]{"av","haha","iloveyou"}});
//这里也可以改成这样的形式:invoke(null,Object(new String[]{"av","haha","iloveyou"}));
System.out.println(maxLength);
//获取类上的所有公有字段
Field[] fields=claxx.getFields();
for(int i=0;i<fields.length;i++){
Field field=fields[i];
//打印字段名称和字段值
System.out.println(field.getName()+":"+field.get(p1));
}
}
}