黑马程序员----反射

------- android培训java培训、期待与您交流! --------
 
什么是反射机制? 

Java反射是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fieldsmethods的所有信息,并可于运行时改变fields内容或唤起methods

Java反射机制容许程序在运行时加载、探知、使用编译期间完全未知的classes

换言之,Java可以加载一个运行时才得知名称的class,获得其完整结构。

简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。

JAVA反射机制提供了什么功能?

提供如下功能:

在运行时判断任意一个对象所属的类

在运行时构造任意一个类的对象

在运行时判段任意一个类所具有的成员变量和方法

在运行时调用任一个对象的方法

在运行时创建新类对象

在使用Java的反射功能时,基本首先都要获取类的Class对象,再通过Class对象获取其他的对象。

反射机制的优点与缺点: 

     为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念, 

     静态编译:在编译时确定类型,绑定对象,即通过。 

     动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,有以降低类之间的藕合性。 

     一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发

它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。

Java程序中的各个Java类属于同一类事物,描述这类事物的Java类就是Class类。

一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不同的,所以它们在内存中的内容是不同的;

获得Class对象

每个类被加载后,系统会为该类生成对应的Class对象,通过Class对象可以访问到JVM中的这个类,

3种方式:

1调用某个类的class属性获取Class对象,如Date.class会返回Date类对应的Class对象(其实就是得到一个类的一份字节码文件)

2使用Class类的forName(String className)静态方法,className表示全限定名;如String的全限定名:java.lang.String;

3调用某个对象的getClass()方法。该方法属于Object类;

Class<?> clz = new Date().getClass();

 

public class Demo{
	public static void main(String[] args) throws Exception {
		//获得Class对象的方法(三种)
		method_1();
	}
	//一:调用属性
	public static void method_1(){
		Class<String> c = String.class;
		System.out.println(c);
		Class<String> c2 = String.class;
		System.out.println(c == c2);
	}
	//二:使用forName()方法
	public static void method_2() throws Exception{
		Class<String> c = String.class;
		//Class cla = Class.forName("String");//ERROR,
		Class<String> cla =(Class<String>)Class.forName("java.lang.String");
		System.out.println(c == cla);//true
	}
	//三:利用对象调用Object的getClass方法;
	public static void method_3(){
		Class<String> c = String.class;
		Class c3 = new String().getClass();
		System.out.println(c == c3);	
	}
}


 

method_1()运行结果:

 

class java.lang.String

true

method_2()运行结果:

 

true

method_3()运行结果:

 

true


 


九个预定义Class对象

基本的 Java 类型(booleanbytecharshortintlongfloatdouble)和关键字void通过class属性也表示为Class 对象;

Class类中boolean isPrimitive() :判定指定的Class 对象是否表示一个基本类型。

包装类和Void类的静态TYPE字段;

Integer.TYPE == int.class ; 

Integer.class == int.class;

数组类型的Class实例对象:

Class<String[]> clz = String[].class;

数组的Class对象如何比较是否相等?数组的维数和数组的类型;

Class类中 boolean isArray():判定此 Class对象是否表示一个数组类型。

Class中得到构造方法Constructor、方法Method、字段Field

常用方法:

Constructor类用于描述类中的构造方法:

Constructor<T> getConstructor(Class<?>... parameterTypes)

返回该Class对象表示类的指定的public构造方法;

Constructor<?>[] getConstructors()

返回该Class对象表示类的所有public构造方法;

Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)

返回该Class对象表示类的指定的构造方法,和访问权限无关;

Constructor<?>[] getDeclaredConstructors()

返回该Class对象表示类的所有构造方法,和访问权限无关;

Method类用于描述类中的方法:

Method getMethod(String name, Class<?> ... parameterTypes)

返回该Class对象表示类和其父类的指定的public方法;

Method[] getMethods(): 

返回该Class对象表示类和其父类的所有public方法;

Method getDeclaredMethod(String name, Class<?>... parameterTypes)

返回该Class对象表示类的指定的方法。和访问权限无关,但不包括继承的方法;

Method[] getDeclaredMethods(): 获得类所有的方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法;

利用反射创建对象

创建对象:

1使用Class对象的newInstance()方法创建该Class对象的实例,此时该Class对象必须要有无参数的构造方法。

2使用Class对象获取指定的Constructor对象,再调用ConstructornewInstance()方法创建对象类的实例,此时可以选择使用某个构造方法。如果这个构造方法被私有化起来,那么必须先申请访问,将可以访问设置为true

使用反射调用方法

每个Method的对象对应一个具体的底层方法。获得Method对象后,程序可以使用Method里面的invoke方法来执行该底层方法。

Object invoke(Object obj,Object ... args):obj表示调用底层方法的对象,后面的args表示传递的实际参数。

如果底层方法是静态的,那么可以忽略指定的 obj 参数。该参数可以为null,想想为什么?

如果底层方法所需的形参个数为 0,则所提供的args 数组长度可以为0 null

不写,null,new Object[]{}

若底层方法返回的是数组类型,invoke方法返回的不是底层方法的值,而是底层方法的返回类型;

 

 


------- android培训java培训、期待与您交流! -------- 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值