java的反射机制

来源:互联网 发布:jsp sql 动态网页 编辑:程序博客网 时间:2024/06/02 05:31

一:玩反射

 

1

在运行状态中,任意一个class文件,都可以找到这个类的所有属性和方法:

对任意一个对象,都可以调用它的任意一个方法和属性;

动态调用类中的信息,就是反射:

可以理解为对类的解剖;

2

要想对字节码文件进行解剖,必须要有字节码文件对象;

下面看第一种方法,怎么样拿到类;

测试代码:Person:

package test;

import java.io.Serializable;

public class Person implements Serializable {

private String name;

private int age;

public Person() {

super();

System.out.println("我是无参构造");

}

 

public Person(String name, int age) {

super();

this.name = name;

this.age = age;

System.out.println("我是有参构造");

}

 

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

 

public void show() {

 

System.out.println("我要展示L");

}

 

public void fun() {

System.out.println(name + ".....我是" + name);

 

}

}

 

package test;

 

public class Test1 {

 

public static void main(String[] args) {

// TODO Auto-generated method stub

getClassObject();

}

 

public static void getClassObject(){

Person p1 = new Person();

Class class1 = p1.getClass();

Person p2 = new Person();

Class class2 = p2.getClass();

System.out.println(p1==p2);

System.out.println(class1==class2);

//我是无参构造

//false

//true

}

}

这种方法的缺点就是说:  必须要知道具体的类,比如上面这个Person类,

下面是第二种方法:

.class来获取对应的Class对象;

package test;

 

public class Test1 {

 

public static void main(String[] args) {

// TODO Auto-generated method stub

getClassObject();

}

 

public static void getClassObject(){

Class class1 = Person.class;

Class class2 = Person.class;

System.out.println(class1==class2);//true

}

}

 

第二种方法还是要知道类的名字:还是要用到类中的静态成员;

第三种方法:只要给定类的字符串名称就可以获取该类;

注意:如果不用static 呢: 则是这样写:new Test1().getClassObject();

Classjava.lang包中;Class.forName();

package test;

public class Test1 {

public static void main(String[] args) throws ClassNotFoundException {

// TODO Auto-generated method stub

new Test1().getClassObject();

}

public void getClassObject() throws ClassNotFoundException {

Class className = Class.forName("Person");

System.out.println(className);

}

//Exception in thread "main" java.lang.ClassNotFoundException: Person

}

为什么呢?想想:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

package test;

 

public class Test1 {

 

public static void main(String[] args) throws ClassNotFoundException {

// TODO Auto-generated method stub

new Test1().getClassObject();

 

}

public void getClassObject() throws ClassNotFoundException {

Class className = Class.forName("test.Person");

System.out.println(className);//class test.Person

}

}

 

 

New 跟 反射中的newInstanceOf()的区别:new 省事,但后者更容易扩展;

package test;

 

public class Test1 {

 

public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {

// TODO Auto-generated method stub

new Test1().getClassObject();

 

}

public void getClassObject() throws ClassNotFoundException, InstantiationException, IllegalAccessException {

Person person1 = new Person();

System.out.println(person1);

//结果是:我是无参构造

//       test.Person@42d73fb7

//实际上new开辟空间,同时调用了无参构造;

}

}

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

package test;

 

public class Test1 {

 

public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {

// TODO Auto-generated method stub

new Test1().getClassObject();

 

}

public void getClassObject() throws ClassNotFoundException, InstantiationException, IllegalAccessException {

String name="test.Person";

Class class1= Class.forName(name);

Object person2=class1.newInstance();

System.out.println(person2);

//我是无参构造

//test.Person@25964fe8

 

}

}

结果是一样的。

那个new ,是先根据被new的类的名称找到该类的字节码文件,加载到内存,

并创建该字节码文件对象,接着创建字节码文件对应的Person对象;

而反射中的newInstance()呢?  是找到该名称的类文件,加载到内存,产生Class对象;

从而产生该类的对象;

造出对象:

Person p1 = new Person(xiaoqiang,25);

相当于:

Class class1= Class.forName("test.Person");

Constructor  con= class1.getConstructor(String.class,int.class);

Object obj =con.newInstance("xiaoqiang",25);

String p1=obj.toString();

System.out.println(p1);

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

getDeclaredFields()的用法

Class class1= Class.forName("test.Person");

Field[] field =class1.getDeclaredFields();

for(Field f:field){

System.out.println(f);//private java.lang.String test.Person.name

                      //private int test.Person.age

}

说白了,就是查看Person类里面的所有属性成员;

而另外一个呢,getFields()只能访问公有的属性;

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Class class1=Class.forName("test.Person");

Field f=class1.getDeclaredField("age");

Field f1 = class1.getDeclaredField("name");

f.setAccessible(true);//暴力访问f属性

f1.setAccessible(true); //暴力访问f1属性

Object obj =class1.newInstance();

f.set(obj, 10);

f1.set(obj, "xiaoqiang");

System.out.println(obj);//我是无参构造      xiaoqiang     10

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

getDeclarMethod();

说白了,加上declar,就是访问所有的;包括私有;

Class class1= Class.forName("test.Person");

Method method =class1.getDeclaredMethod("show"null);

Object obj = class1.newInstance();

     method.invoke(obj, null); 我是无参构造

我要展示L

2

Class class1= Class.forName("test.Person");

Method method =class1.getDeclaredMethod("show"null);

Constructor con = class1.getConstructor(String.class,int.class);

Object obj = con.newInstance("xiaoqiang",25);

     method.invoke(obj, null); 我是有参构造

我要展示L

 

带有参数的:

Class class1= Class.forName("test.Person");

Method method =class1.getMethod("fun", String.class);

Constructor con = class1.getConstructor(String.class,int.class);

Object obj = con.newInstance("xiaoqiang",25);

     method.invoke(obj, "yes");

     //我是有参构造            yes.....我是yes

     -------------------------------------------------------------------------

用配置文件来学习反射:

src下面新建一个配置文件:test.properties;

File file = new File(“test.properties”);

 

Property property = new Property();

 

FileInputStream in = new FileInputStream(file);

Property.load(in);

 

File file = new File("fi.properties");

Properties pro = new Properties();

FileInputStream in = new FileInputStream(file);

pro.load(in);

for(int x =0;x<pro.size()-1;x++){

System.out.println(pro.getProperty("user1"));

System.out.println(pro.getProperty("user2"));

}

}

结果是:

//zhangsan

//lisi

 

 

 

 

 

0 0
原创粉丝点击