黑马程序员_java反射学习

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

            反射就是在程序运行时,允许改变程序结构或变量类型。

 Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
Java中有一个类Class代表某个类的字节码。既然代表某个类的字节码,当然提供了加载某个类字节码的方法。其中forName()方法用于加载某个类的字节码到内存中,并使用Class对象进行封装。
得到Class对象的两种方式:
(1)、类名.class
(2)、对象名.class

类中最重要的三个信息

如果要对一个类的信息重要性进行排名的话,那么这三个信息理应获得前三的名次。它们分别是:构造函数、成员函数、成员变量。

也许你不同意我的排名,没关系。对于Java反射来说,这三个信息与之前介绍的基本信息相比较而言,有着本质的区别。那就是,之前的信息仅仅是只读的,而这三个信息可以在运行时被调用(构造函数和成员函数)或者被修改(成员变量)。所以,我想无可否认,至少站在Java反射机制的立场来说,这三者是最重要的信息。

下面,让我们分别了解一下这三个重要信息的获取方式。另外,我们将在后面的章节,详细介绍他们的调用方式或者修改方式。

构造函数

如果我们将Java对象视为一个二进制的生活在内存中生命体的话,那么构造函数无疑可以类比为Java对象生命体的诞生过程。我们在构造函数调用时为对象分配内存空间,初始化一些属性,于是一个新的生命诞生了。

Java是纯面向对象的语言,Java中几乎所有的一切都是类的对象,因此可想而知构造函数的重要性。

Java反射机制能够得到构造函数信息实在应该是一件令人惊喜的事情。正因为此,反射机制实质上才拥有了孵化生命的能力。换句话言之,我们可以通过反射机制,动态地创建新的对象。

构造函数

获取构造函数的方法有以下几个:

Constructor getConstructor(Class[] params) 

Constructor[] getConstructors()

Constructor getDeclaredConstructor(Class[] params) 

Constructor[] getDeclaredConstructors()

1、 反射类的构造函数示例

          package com.model;

public class Person {

private String name;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Person() {

System.out.println("person");

}

public Person(String name) {

System.out.println(name);

}

}

JUnit测试类测试方法:

// 反射类的构造函数 pulic 类型getConstructor
@Test
public void test1() throws Exception {
Class class1 = Class.forName("com.model.Person");
Constructor c = class1.getConstructor(null);
Person person = (Person) c.newInstance(null);
person.setName("haha");
System.out.println(person.getName());
}

成员函数

如果构造函数类比为对象的诞生过程的话,成员函数无疑可以类比为对象的生命行为过程。成员函数的调用执行才是绝大多数对象存在的证据和意义。Java反射机制允许获取成员函数(或者说成员方法)的信息,也就是说,反射机制能够帮助对象践行生命意义。通俗地说,Java反射能使对象完成其相应的功能。

和获取构造函数的方法类似,获取成员函数的方法有以下一些:

Method getMethod(String name, Class[] params)

Method[] getMethods()

Method getDeclaredMethod(String name, Class[] params) 

Method[] getDeclaredMethods() 

其中需要注意,String name参数,需要写入方法名。关于访问权限和确定性的问题,和构造函数基本一致。

//反射类的方法示例

package com.model;

import java.io.InputStream;
import java.util.List;

public class Person {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Person() {
System.out.println("person");
}

public Person(String name) {
System.out.println(name);
}

public Person(String name, int pwd) {
System.out.println("name:" + name + "pwd:" + pwd);
}

private Person(List list) {
System.out.println("person--list");
}

//------ 成员方法 
public void m1() {
System.out.println("无参函数m1");
}

public void m1(String name,int pwd) {
System.out.println(name+"--"+pwd);
}
public Class[] m1(String name,int[] pwd) {
System.out.println(name);
for(int i:pwd){
System.out.println(i);
}
return new Class[]{String.class};

}
private void m1(InputStream in) {
System.out.println(in);

}

public static void m1(int num) {
System.out.println(num);

}

public static void main(String[] args){
System.out.println("this is main method!");
}

public static void m2(int[] args){
for(int s:args){
System.out.println(s);
}
System.out.println("this is m2 method!");
}
//---字段
public String Pwd="aaaa";
private  int age;
        private  static int old;
}

// -----------反射类的方法

JUnit测试类测试方法


// public void m1() {
@Test
public void testM1() throws Exception {
Person person = new Person();
Class class1 = Class.forName("com.model.Person");
Method method = class1.getMethod("m1", null);
method.invoke(person, null);


}


// public void m1(String name,int pwd) {
@Test
public void testM2() throws Exception {
Person person = new Person();
Class class1 = Class.forName("com.model.Person");
Method method = class1.getMethod("m1", String.class, int.class);
method.invoke(person, "hah", 123);
}


// public Class[] m1(String name,int[] pwd) {
@Test
public void testM3() throws Exception {
Person person = new Person();
Class class1 = Class.forName("com.model.Person");
Method method = class1.getMethod("m1", String.class, int[].class);
Class[] classArray = (Class[]) method.invoke(person, "hah", new int[] {
1, 2, 3 });
System.out.println(classArray.length);
}


// private void m1(InputStream in) {
@Test
public void testM4() throws Exception {
Person person = new Person();
Class class1 = Class.forName("com.model.Person");
Method method = class1.getDeclaredMethod("m1", InputStream.class);
method.setAccessible(true);
method.invoke(person, new FileInputStream("D:\\1.txt"));


}

成员变量

成员变量,我们经常叫做一个对象的域。从内存的角度来说,构造函数和成员函数都仅仅是Java对象的行为或过程,而成员变量则是真正构成对象本身的细胞和血肉。简单的说,就是成员变量占用的空间之和几乎就是对象占用的所有内存空间。

获取成员变量的方法与上面两种方法类似,具体如下:

Field getField(String name)

Field[] getFields()

Field getDeclaredField(String name)

Field[] getDeclaredFields()

其中,String name参数,需要写入变量名。关于访问权限和确定性的问题,与前面两例基本一致。

//反射类中成员变量

Person实体类同上

JUnit测试类方法如下:

   // ---反射public字段
@Test
public void testF1() throws Exception {
Person person = new Person();
Class class1 = Class.forName("com.model.Person");
Field field = class1.getField("Pwd");
// 获取字段值
Object value = field.get(person);
// 获取字段类型
Class type = field.getType();
if (type.equals(String.class)) {
String string = (String) value;
System.out.println(string);
}


// 设置字段值
field.set(person, "haha");
System.out.println(person.Pwd);
}


// ---反射private字段
@Test
public void testF2() throws Exception {
Person person = new Person();
Class class1 = Class.forName("com.model.Person");
Field field = class1.getDeclaredField("age");
field.setAccessible(true);
// 获取字段值
Object value = field.get(person);
// 获取字段类型
Class type = field.getType();
if (type.equals(int.class)) {
int i = (Integer) value;
System.out.println(i);
}
//也可以为private字段赋值
field.set(person, 888);
System.out.println(field.get(person));

}

呵呵,看到了吧,java的反射很强大的啊....

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

详情请查看:http://edu.csdn.net/heima






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值