反射

原创
2017/11/28 18:52
阅读数 88

概要解释

github地址:

 

目录图

 

学习地址:MOOC

反射的操作会绕过编译。

Java里:除了基本数据类型和静态成员两部分不能当成对象外,其余一切都可以看成对象。

class作为对象是java.lang.Class类的对象实例。

class构造函数

/*Class类中默认的构造函数
 *Private class():只能被JVM创建,外界不能显示创建或者调用。
 * Private constructor. 
 *Only the Java Virtual Machine creates Class objects.

 * ClassLoader归JVM部分
 */
private Class(ClassLoader loader) {
    // Initialize final field for classLoader.  The initialization value of non-null
    // prevents future JIT optimizations from assuming this final field is null.
    classLoader = loader;
}

具体应用

Class类的反射使用

3种获取类类型的方法

 1.类名.class  

2.对象名.getClass()  

3.Class.forName(" ")

Class c1=Foo.class;
Class c2=foo01.getClass();
Class c3=null;
//写对象地址要具体到类名。
c3=Class.forName("reflect.base.Foo");

创建实例的方法

创建类的实例的方法:  

1.通过类对象反射创建,创建后需要注意返回类型可能需要类型转换。

try {
			Foo foo=(Foo)c1.newInstance();
			foo.print();
		}
		catch (InstantiationException e) {
			e.printStackTrace();
		}
		catch (IllegalAccessException e) {
			e.printStackTrace();
		}

Java类加载机制

编译时刻加载类是静态加载,运行时刻加载类是动态加载。

New创建对象是静态加载类,而静态加载就意味着编译时刻就会加载所有可能用到的类,只要有一个没有就回报错。

动态加载:加载当前需要的类就可以,对于编译指令没涉及到的类不会管。

获取方法

java.lang.reflect.Method

基本类型、封装类、关键字都可以.class获得
获取类->得到返回类型的类类型->得到返回值类型-> 得到方法的名称->获取参数列表的类类

/**
 * getMethods()获取的是所有的public类型的函数
 * getDeclaredMethods()获取的是该类自己声明的方法。
 */
//获取类
Class c=obj.getClass();
System.out.println("类名称是" + c.getName());
Method[] ms=c.getMethods();
Method[] mes=c.getDeclaredMethods();
for (int i = 0; i <ms.length ; i++) {
   //得到返回类型的类类型
   Class returnType=ms[i].getReturnType();
   //得到返回值类型
   System.out.print(returnType.getName() + " ");
   //得到方法的名称
   System.out.print(ms[i].getName()+"(");

   Class[] paramTpres=ms[i].getParameterTypes();
   //获取参数列表的类类型
   for (Class class1:paramTpres
       ) {
      System.out.print(","+class1.getSimpleName().toString());
   }
   System.out.println(")");
}

获取成员变量信息

java.lang.reflect.Filed

/**
 * getFields()获取的是所有的public成员变量的的信息
 * getDeclaredFields()获取的是该类自己声明的成员变量的信息。
 */
//获取类
Class c=obj.getClass();
System.out.println("类名称是" + c.getName());
Field[] fs=c.getFields();
Field[] fis=c.getDeclaredFields();
for (Field field:fs
    ) { //得到成员变量的类型的类类型
   Class typeName=field.getType();
   String fieldName=field.getName();
   System.out.println(typeName + ":" + fieldName);

获取构造方法

java.lang.reflect.Constructor

获得一个类的类类型->获得一个类的信息

		Class c=obj.getClass();
		System.out.println("类名称是" + c.getName());
		//构造函数也是对象
		//getConstructors得到所有的构造函数
		//getConstructors得到自己定义的的构造函数
		Constructor[] cs=c.getConstructors();
		Constructor[] cos=c.getDeclaredConstructors();
		for (Constructor con:cs
				) {
			System.out.print(con.getName() + "  (");
			Class[] paraTypes=con.getParameterTypes();

			for (Class cla:paraTypes
				 ) {
				System.out.print(","+cla.getSimpleName());
			}
			System.out.println(")");
		}

方法的反射操作

获取方法的对象->用方法对象 反射操作

method.invoke(对象名,参数列表)//方法的名称和参数列表结合才能唯一决定某个方法。

class字节码是编译之后的,反射是编译之后的操作。

集合的范型是防止错误输入的,旨在编译阶段提示,但是集合本身是当成Object(设计的目的就是为了可以存储不同的类型)处理的。所以编译后,集合的范型是去范型化的。

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部