java反射(reflect)
java框架设计的灵魂
反射
Test t = new Test();
t.test();
类的类类型(class type)创建实例对象,
java是面对对象
万物节对象
基础数据类型(int,byte,long,short,char,double,float,boolean)
类是不是对象?
类也是对象,这个对象的创建是在classLoad时由JVM创建。
public class A{
}
静态加载和动态加载
通过new的方式创建对象,属于静态加载
Excel excel = new Excel();
一定要先通过编译。
动态加载,通过反射的方式创建对象。可以绕过编译
eg:
entity.Student:
package enity;
public class Student {
public void test(String a,int b){
System.out.println("Student.test()-----");
}
public void test1(String a,int b,int c){
System.out.println("Student.test()");
}
public void test(int a,int b){
System.out.println("a+b="+(a+b));
}
}
test.TestClass:
package test;
import java.lang.reflect.Method;
import enity.Student;
public class TestClass {
public static void main(String[] args) throws Exception {
Student stu = new Student();
// stu.test();
//由三种方式得到Student类的类类型
//1,由对象的getClass()方法获取类类型
Class c1 = stu.getClass();
System.out.println(c1);
//2,通过类名.class获取,说明每一个类都有一个class的静态属性
Class c2 = Student.class;
System.out.println(c1==c2);
//3,
Class c3 = Class.forName("enity.Student");
System.out.println(c3);
System.out.println(c1==c3);
//通过类的类类型实例化对象
// Student stu1 = (Student)c1.newInstance();
// stu1.test();
//通过反射调用方法
Method m = c1.getMethod("test");//得到c1类中的test方法,返回的是Method对象
//调用方法
m.invoke(stu);//反射调用stu对象中的m方法
try {
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
test.TestMethod:
package test;
import java.lang.reflect.Method;
import enity.Student;
public class TestMethod {
/**
* 通过反射得到obj对象中所有的方法
* @param obj
*/
public static void getMethods(Object obj){
//通过obj.getClass()获得该对象的类类型
Class c = obj.getClass();
System.out.println("完整的类名:"+c.getName());
System.out.println("简单的类名:"+c.getSimpleName());
//通过c得到该对象中所有的方法
//c.getMethods();//包括从父类继承过来的方法,private不能得到
Method[] methods = c.getDeclaredMethods();//得到该类中所有的方法,不问访问权限,不能得到父类继承的方法
for (Method method : methods) {
String name = method.getName();//得到方法名
Class c1 = method.getReturnType();//得到方法的返回值类型
int role = method.getModifiers();//得到方法的访问权限
Class[] cs = method.getParameterTypes();//得到方法所有的参数,
System.out.print("方法名:"+role+" "+c1.getSimpleName()+" "+name+"(");
for (int i=0;i<cs.length;i++) {
//class1代表方法中的每一个参数类型
if(i<cs.length-1){
System.out.print(cs[i].getSimpleName()+",");
}else{
System.out.print(cs[i].getSimpleName());
}
}
System.out.println(")");
}
}
public static void main(String[] args) throws Exception {
// getMethods(new Student());
//Student
Class c = Class.forName("enity.Student");
// c.newInstance();
//得到单个方法 test 是方法名,int.class,int.class参数列表
Method m = c.getMethod("test",int.class,int.class);
//通过method对象的 invoke方法 反射调用
m.invoke(new Student(), 1,2);
}
}
使用反射完成一个简单的办公软件的启动
Excel.java
class Excel implements IOffice{
public void start(){
System.out.println("excel....start.....");
}
}
IOffice.java
interface IOffice{
public void start();
}
Office.java
public class Office{
public static void main(String[] args){
/*
静态加载
if("Excel".equals(args[0])){
Excel excel = new Excel();
excel.start();
}else if("Word".equals(args[0])){
Word word = new Word();
word.start();
}
*/
//动态加载
try{
Class c = Class.forName(args[0]);
//通过c创建该类的实例对象
IOffice io = (IOffice)c.newInstance();
io.start();
}catch(Exception e){
e.printStackTrace();
}
}
}
PPT.java
class PPT implements IOffice{
public void start(){
System.out.println("PPT...start....");
}
}
Word.java
class Word implements IOffice{
public void start(){
System.out.println("word...start....");
}
}