黑马程序员----反射

来源:互联网 发布:nginx 多域名配置 编辑:程序博客网 时间:2024/05/21 17:05

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

一、反射
关于反射的基石——Class类
该类描述java中的一切事物,该类描述了关于类事物的类名字、类的访问属性、类所属于的包名、字段名称的列表、
方法名称的列表等。
Class实例化代表内存中一个字节码,所谓字节码,就是当java虚拟机加载某个类的对象时,首先需要把硬盘上关于
该类的二进制源码编译成class文件的二进制代码(字节码),然后把关于Class文件的字节码加载到内存中,然后再
创建关于该类的对象。
获取Class类的对象的——字节码的3种方法
1、getClass()方法
Data d;
Class dc = d.getClass();
2、通过Class类中的静态方法forName()获取与字符串对应的Class对象
Class dc = Class.forName("d");
3、通过 类名.class 形式。
Class dc = Data.class 
例:
*/
class ClassTest
{
public static void main(String[] args) throws ClassNotFoundException,
InstantiationException,IllegalAccessException
{
String s1 = "1234";//创建一个字符串变量s1
//获取s1和String类的字节码
Class c1 = s1.getClass();
Class c2 = String.class;
Class c3 = Class.forName("java.lang.String");
//比较字节码是否相同
System.out.println("***************");
System.out.println("c1和c2是否是同一个对象"+(c1==c2));
System.out.println("c1和c3是否是同一个对象"+(c1==c3));
System.out.println("***************");
//检测是否为基本类型
System.out.println("String是否是基本类型"+String.class.isPrimitive());
System.out.println("int是否是基本类型"+int.class.isPrimitive());
//检测int和Integer是否指向同一字节码
System.out.println("int和Integer的字节码是否是同一对象"+(int.class == Integer.class));
System.out.println("int和Integer.TYPE的字节码是否是同一对象"+(int.class==Integer.TYPE));
//关于数组方面的字节码
System.out.println("***************");
System.out.println("int[]是否是基本类型"+int[].class.isPrimitive());
System.out.println("int[]是否是数组类型"+int[].class.isArray());
}
}
/*
反射的基本应用
反射一般会涉及到Class(表示一个类的类)、Field(表示属性的类)、
Method(表示方法的类)和Constructor(表示类的构造方法的类)
*/
1、关于构造方法的反射
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargeException;
public class ConstructorRef
{
public static void main(String[] args) throws SecurityException,NoSuchMethodException,
InstantiationException,IllegalArgumentException,InstantiationException,IllegalAccessException,
InvocationTargetException
{
//创建字符串的常用方法
String s1 = new String(new StringBuffer("cjgong"));
//获取String类的构造函数对象
Constructor cs1 = String.class.getConstructor(StringBuffer.class);
//通过Constructor类对象的方法创建字符串
String s11 = (String) cs1.newInstance(new StringBuffer("cjgong"));
System.out.println("*************************");
System.out.println("s1的第5个元素为"+s1.charAt(4));
System.out.println("s11的第5个元素为"+s11.charAt(4));
System.out.println("*************************");
}
}
2、关于成员字段的反射
public class Point
{
//创建4个字段
private int x;
public int y;
public String s1 = "ababababa";
public String s2 = "aaaaaabbbb";
public Point(int x,int y)
{
super();
this.x = x;
this.y = y;
}
public Point(int x,int y,String s1,String s2)
{
super();
this.x = x;
this.y = y;
this.s1 = s1;
this.s2 = s2;
}
public String toString()
{
return "s1的值"+s1+"s2的值"+s2;
}
}
public class Test
{
public static void main(String[] args) throws SecurityException,NoSuchFieldException,
IllegalArgumentException,IllegalAccessException
{
Point point = new Point(3,4);
//获取字段y的值
Field fieldY = point.getClass().getField("y");
System.out.println("输出public属性字段"+fieldY.get(point));
Field fieldX = point.getClass().getDeclaredField("x");
fieldX.setAccessible(true);
System.out.println("输出private属性字段"+fieldX.get(point));
chang(point);
System.out.println(point);
}
public static void chang(Object obj) throws IllegalArgumentException,IllegalAccessException
{
Field[] fields = obj.getClass().getFields();
for(Field field:fields)
{
if(String.class == field.getType())
{
String oldValue = (String) field.get(obj);
String newValue = oldValue.replace('a','b');
field.set(obj,newValue);
}
}
}
}
3、关于成员方法的反射
Method表示方法的类
invoke()方法 public Object invoke(Object obj,Object...args)
第一个参数为实体对象,第二个参数为方法调用所需的参数。
//反射的高级应用
数组等集合方法的反射
通过Class实例对象的getName()方法可以获取字节码名字,例如"[[I"表示二维数组,类型为int.
通过工具类Arrays的asList()方法可以输出数组中参数的值。

0 0
原创粉丝点击