您的位置:首页 > 编程语言 > Java开发

java反射

2016-05-24 10:49 549 查看
Java反射(反射就是把Java类中的各种成分映射成相对应的Java类)

该文章根据张孝祥老师在课程中提到的知识点进行总结

所谓反射,是指在运行时状态中,获取类中的属性和方法,以及调用其中的方法的一种机制。这种机制的作用在于获取运行时才知道的类(Class)及其中的属性(Field)、方法(Method)以及调用其中的方法,也可以设置其中的属性值。

Java中实现反射的几种方法:

注意:所有得类的对象都是地址(字节码),所以用不同方法反射出来的同一个对象, 都是相同的。

1、 通过Class.forName(“”)方法加载字符串,就可以得到该字符串所代表的类的对象;

注意:字符串必须为类的全名 = 包名 + 类名

String str = Class.forName("java.lang.String");


2、通过类名调用class属性得到该类的Class对象。

Class cla = String.class;


3、通过实例的getClass()方法

String  str = new String("");
Class cla = str.getClass();


4、如果是基本类型的包装类,则可以通过调用包装类的TYPE属性来获得该包装类的对象

(数据类型对应的包装类 Integer, Double, Boolean, Byte, Short, Character, Long, Float)

Class cla = Integer.TYPE;


Constructor 获取反射对象的构造方法

使用Constructor得到需要反射对象的构造方法 然后使用其对象.newInstance创建出Object实例 然后就可以直接使用

Constructor con = String.class.getConstructor(StringBuffer.class);


使用newInstance直接使用反射的对象.newInstance()创建出Object实例

Class.forName("java.lang.String").newInstance();


Field类 可以获取对象中的共有属性

语法:

Object obj = new Object(); //声明一个对象实例
Field field = obj.getClass().getField("公共属性"); //获取到对象的字节码(字节码中包含方法变量等..) 调用获取属性的方法 getField();

Field field1 = obj.getClass.getDeclaredField("所有属性都可以"); //不管是私有属性,或者共有属性,都可以获取到

field1.setAccessible(true);  如果访问的是私有属性必须加上这句 强力访问

System.out.println(field.get(obj)); //使用field获取某个对象的属性值

小实例:(获取Object的所有属性,并且将属性的value值进行替换)
public class ClassDemo{
public String a = "123";
public String b = "345";
private String c = "456";

public String toString(){
return "a: " + a + "b: " + b + "c: " + c;
}
}

public static void main(String[] args){
ClassDemo cla = new ClassDemo();

Field[] field = cla.getClass().getDeclaredFields(); //获取到所有的属性

for(Field fie : field){
fie.setAccessible(true);
if(fie.getType() == String.class){ //判断如果属性的类型是String类型的【这个地方用==是因为String类型只会产生一个字节码直接用==即可,当然也可以用equeals】

String oldValue = (String)fie.get(cla);
String newValue = oldValue.replace('b', 'a');
fie.set(cla, newValue);
}
}
}


Method类,获取对象实例中的所有方法(同获取属性一样)

ClassDemo  clas = new ClassDemo();
Method method = clas.getClass().getMethod("toString", null);
String str = (String)method.invoke(clas, null);


对接受数组类型参数的方法进行反射调用

注意: 因为执行的是main方法,所以这里invoke首个参数为空.

public class a{
public static void main(String[] args){
Method method = Class.forName("com.class.b").getMethod("main", String[].class);
//这里为什么要先把String数组强转成Object? 如果不强转则会报 java.lang.IllegalArgumentException: wrong number of arguments异常。
//因为b.main方法中接受的是一个String类型的数组,但是在执行过程中他会把传过来的数组解析(打开)识别成传过来两个String类型的参数 所以这个地方必须强转。

--1. method.invoke(null, (Object)new String[]{"111", "222"});
--2. method.invoke(null, new Object[]{new String[]{"111", "222"}});
}
}
class b {
public static void main(String[] args){
for(String arg : args){
System.out.println(arg);
}
}
}


对数组进行反射

public class test{
public static void main(String[] args){
Object obj = new Object[]{"111", 11, 'a'};
shuzeReflect(obj);
}

public static void shuzeReflect(Object obj){
if(obj.getClass().isArray()){  //首先判断传入的参数是不是数组
int leng = Array.getLength(obj); //如果是数组,则获取该数组的length
for (int i = 0; i < leng; i++) {
System.out.println("数组中的Value : " + Array.get(obj, i)); //print.. 111, 11, a
System.out.println("数组中Value的类型" + Array.get(obj, i).getClass().getName()); //print  java.lang.String, Integer, Character
}
} else {
System.out.println(obj);
}

}
}


如有遗漏,谢谢补充,共同学习,共同进步。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 反射