重学JAVA基础(二):Java反射
看一下百度的解释:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息 以及动态调用对象的方法的功能称为java语言的反射机制。
先看一下一个例子:
这是最简单的反射使用方法,通过反射来调用类的方法。
下面通过一个需求来做反射实验:有3种人类(黄,白,黑),分别继承于Human类,都有人类的共同操作Behaviour
/** * 行为,区别于动物 * @author tomsnail * @date 2015年4月1日 上午10:10:42 */ public interface Behaviour{ public void eat(); public void sleep(); public void think(); public void sport(); public void work(); }
import java.util.Random; /** * 皮肤类型 * @author tomsnail * @date 2015年4月1日 上午11:41:33 */ public enum SkinType{ yellow,white,black; public static SkinType getSkinType(){ int r = new Random().nextInt(3); switch(r){ case 0:return SkinType.yellow; case 1:return SkinType.white; default:return SkinType.black; } } }
public abstract class Human implements Behaviour{ private String name; private short age; private short sex; private SkinType skin; public String getName() { return name; } public void setName(String name) { this.name = name; } public short getAge() { return age; } public void setAge(short age) { this.age = age; } public short getSex() { return sex; } public void setSex(short sex) { this.sex = sex; } public SkinType getSkin() { return skin; } public void setSkin(SkinType skin) { this.skin = skin; } /** * 构造方法要传皮肤颜色,以区分不同的人种 * @author tomsnail * @date 2015年4月1日 上午10:06:48 */ public Human(SkinType skin) { this.skin = skin; this.name = skin.toString()+"_"+Goddess.counter++; } }
public class WhiteHuman extends Human{ public WhiteHuman() { super(SkinType.white); } public WhiteHuman(SkinType skinType) { super(skinType); System.err.println("我是白人,我在"); } @Override public void eat() { System.err.println("我是白人,我在eat"); } @Override public void sleep() { System.err.println("我是白人,我在sleep"); } @Override public void think() { System.err.println("我是白人,我在think"); } @Override public void sport() { System.err.println("我是白人,我在sport"); } @Override public void work() { System.err.println("我是白人,我在work"); } private void selfMethod(){ System.out.println("这是白人私有方法"); } }
public class YellowHuman extends Human{ public YellowHuman() { super(SkinType.yellow); } public YellowHuman(SkinType skinType) { super(skinType); System.err.println("我是黄种人,我的皮肤颜色是:"+skinType); } @Override public void eat() { System.err.println("我是黄种人,我在eat"); } @Override public void sleep() { System.err.println("我是黄种人,我在sleep"); } @Override public void think() { System.err.println("我是黄种人,我在think"); } @Override public void sport() { System.err.println("我是黄种人,我在sport"); } @Override public void work() { System.err.println("我是黄种人,我在work"); } private void selfMethod(){ System.out.println("这是黄种人私有方法"); } }
public class BlackHuman extends Human{ public BlackHuman() { super(SkinType.black); } public BlackHuman(SkinType skinType) { super(skinType); System.err.println("我是黑人,我的皮肤颜色是:"+skinType); } @Override public void eat() { System.err.println("我是黑人,我在eat"); } @Override public void sleep() { System.err.println("我是黑人,我在sleep"); } @Override public void think() { System.err.println("我是黑人,我在think"); } @Override public void sport() { System.err.println("我是黑人,我在sport"); } @Override public void work() { System.err.println("我是黑人,我在work"); } private void selfMethod(){ System.out.println("这是黑人私有方法"); } }
/** * 女娲 * @author tomsnail * @date 2015年4月1日 上午10:20:16 */ public class Goddess { public static int counter = 0; private static final String[] humanClasss = new String[]{"com.tomsnail.java.test.reflec.BlackHuman","com.tomsnail.java.test.reflec.WhiteHuman","com.tomsnail.java.test.reflec.YellowHuman"}; //小伙伴 private List<Human> companions = new ArrayList<Human>(); private static final int number = 10; /** * 造人 * @author tomsnail * @date 2015年4月1日 上午10:21:03 */ public void createHuman(){ int i=number; while(--i>0){ String className = randomHuman(); try { Class humanClass = Class.forName(className); Human human = null; if(System.currentTimeMillis()%i==1){ System.out.println("发生意外,创造一个不知道什么的人"); Constructor constructor = humanClass.getConstructor(SkinType.class);//构造方法 human = (Human) constructor.newInstance(SkinType.getSkinType());//通过构造方法创建一个对象 }else{ System.out.println("女娲创造一个 "+humanClass.getSimpleName()); human = (Human) humanClass.newInstance(); } companions.add(human); } catch (Exception e) { e.printStackTrace(); } } } private String randomHuman(){ int r = new Random().nextInt(3); return humanClasss[r]; } /** * 生活 * @author tomsnail * @date 2015年4月1日 上午10:27:09 */ public void life() throws Exception{ while(true){ try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } Human human = companions.get(new Random().nextInt(number-1)); Class humanClass = human.getClass(); Field[] fs = humanClass.getSuperclass().getDeclaredFields();//父类属性 for(Field f:fs){ System.out.println(f.getName()+":"+humanClass.getMethod("get"+getMethodName(f.getName())).invoke(human, null));//打印出父类属性值 } Method[] ms = humanClass.getSuperclass().getInterfaces()[0].getMethods();//获得接口方法 Method m = ms[new Random().nextInt(ms.length)]; m.invoke(human, null);//执行接口方法 Method pm = humanClass.getDeclaredMethod("selfMethod");//获得私有方法 pm.setAccessible(true);//可访问 pm.invoke(human, null);//执行私有方法 } } /** * 将首字符改为大写 * @author tomsnail * @date 2015年4月1日 上午11:40:48 */ private static String getMethodName(String fildeName) throws Exception{ byte[] items = fildeName.getBytes(); items[0] = (byte) ((char) items[0] - 'a' + 'A'); return new String(items); } public static void main(String[] args) throws Exception { Goddess goddess = new Goddess(); goddess.createHuman(); goddess.life(); } }
女娲创造一个 YellowHuman 女娲创造一个 BlackHuman 女娲创造一个 WhiteHuman 女娲创造一个 WhiteHuman 发生意外,创造一个不知道什么的人 女娲创造一个 BlackHuman 女娲创造一个 YellowHuman 女娲创造一个 WhiteHuman 我是黑人,我的皮肤颜色是:yellow
女娲创造一个 WhiteHuman name:white_7 age:0 sex:0 skin:white 我是白人,我在work
这是白人私有方法 name:white_3 age:0 sex:0 skin:white 我是白人,我在eat
这是白人私有方法 name:white_2 我是白人,我在work age:0 sex:0 skin:white 这是白人私有方法 name:yellow_0 我是黄种人,我在think age:0 sex:0 skin:yellow 这是黄种人私有方法 name:black_1 我是黑人,我在work