【学习笔记】反射

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yuynim/article/details/78374785
API参考】http://tool.oschina.net/apidocs/apidoc?api=jdk-zh    
java.lang.Class;     文档 ->  java.lang  ->  class         

java.lang.reflect;   文档 -> java.lang.reflect -> Constructor,Field,Method...

【教程】

慕课网-反射:http://www.imooc.com/learn/199



一.Class类的使用
1.任何一个类都是Class的实例对象,Class类的实例对象,表示方法:
  例:Foo foo=new Foo();
(1)Class c1=Foo.class;
(2)Class c2=foo.getClass();
(3)Class c3=Class.forName("Foo<类的全称>");
c1,c2,c3都表示了Foo类的类类型(class type)
万事万物皆对象,类也是对象,是Class类的实例对象,这个对象我们称为该类的类类型。


2.通过类的类类型创建该类的对象实例:
 Foo foo=(Foo)c1.newInstance(); //需要强制类型转换,需要有无参数的构造方法


二.动态加载类 
1.动态加载类与静态加载类
 Class.forName("类的全称"); 
 不仅表示了类的类类型,还代表了动态加载类。
 请大家区分编译,运行;
 编译时刻加载类是静态加载类,运行时刻加载类是动态加载类。
 
(1)new创建对象,是静态加载类,在编译时刻就需要加载所有的可能使用到的类。
class Office{
public static void static main(String[] args) {
if("Word".equals(args[0])){
Word w=new Word();     //Word类不存在,需要创建
w.start();
}else if("Excel".equals(args[0])){
Excel e=new Excel();    //Excel类不存在,需要创建
e.start();
}

}


}



(2)通过动态加载类可以实现"用哪个加载哪个,不用不加载"。功能性类尽量使用动态加载。
class OfficeBetter{
public static void static main(String[] args) {
try{
//动态加载类,在运行时刻加载
Class c=Class.forName(args[0]);

//通过类类型,创建该类对象
OfficeAble oa=(OfficeAble)c.newInstance();
oa.start();
}catch(Exception e){
e.printStackTrace();
}

}
}
//共同制定的标准
interface OfficeAble{

public void start();
}

class Word implements OfficeAble{   //添加的功能只需要实现制定的标准接口,不需要更改OfficeBetter的代码
public void start(){
System.out.println("word...start");

}

}
【cmd】
javac Word.java;
javac OfficeBetter.java;
java OfficeBetter Word;
再增加其他功能时,只需编译增加的那个类即可。例如:
javac Excle.java;
java OfficeBetter Excel;

三.获取方法信息,获取成员变量,构造函数信息
关键字都存在类类型.
1.基本数据类型的类类型
Class c1=int.class;//int类的类类型
System.out.println(c1);  //int
Class c2=String.class;
System.out.println(c2);   //class java.lang.String


2.获取方法信息
/*获取任意一个类的全部信息,先获得该类的类类型Class obj.getClass()*/


*Method类是方法对象,一个成员方法就是一个Method对象。java.lang.Method中封装了方法函数的信息
Method[] getMethod() 获取的是所有public的函数,包括父类继承而来的
Method[] getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限

3.获取成员变量
Field[]  getFields() 获得所有成员变量
Field[] getDeclaredFields()  该类自己定义的所有成员变量

4.获取构造函数信息
*构造函数也是对象,java.lang.Constructor中封装了构造函数的信息
Constructor[] getConstructors() 该类的所有公共的构造方法
    Constructor[] getDeclaredConstructors() 该类所有的构造方法
注:要想获得一个类的信息,要先得到他的类类型。


四.Java方法反射的基本操作
(1)如何获取某个方法:获取一个方法就是获取类的信息
1>获取类类型
例如:
A a1=new A();
Class c=a1.getClass();
2>获取方法 名称和参数列表来决定
//获取方法对象   Method getMothod("方法名",参数列表); 获取无参方法时,参数可以不写
例如:
Method c.getMothod("方法名",new Class[]{int.class,int.class});

Method c.getMothod("方法名",int.class,int.class);
(2)方法反射的操作:用Method的实例对象m来进行方法调用,和a1来进行方法调用,和a1.方法()调用效果相同
  //方法如果没有返回值返回null,有返回值返回具体的返回值
  Object method.invoke(对象,参数列表);
例如:
  Object o=m.invoke(a1,new Object[]{10,20});
  Object o=m.invoke(a1,10,20);


五.通过反射了解集合泛型的本质
反射的操作都是编译之后的操作,就是运行时操作
编译之后,集合的泛型时去泛型话的,Java中集合的泛型,是防止错误输入的,只在编译阶段有效,绕过编译就无效了。
验证:我们可以通过方法的反射来操作,绕过编译。绕过编译就绕过了泛型。






猜你喜欢

转载自blog.csdn.net/yuynim/article/details/78374785