一、Class 类
1、概述:
Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class。每个java类都是Class的一个实例对象,它们的内容不同,但是,它们的特征相同,譬如,都有方法,有字段,有父类,有包。对应各个类在内存中的字节码,例如,Person类的字节码,ArrayList类的字节码,等等。
一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不同的,所以它们在内存中的内容是不同的。
2、如何得到各个字节码对应的实例对象( Class类型)
类名.class,例如,System.class
/*Class x1 = Vector类在内存里的字节码
Class x2 = Date类在内存里的字节码*/
Class x1 = Vector.class;
Class x2 = Date.class;
3、如何得到各个字节码对应的实例对象( 以String类型为例)
String str1 = "abc";
Class cls1 = str1.getClass();
Class cls2 = String.class;
Class cls3 = Class.forName("java.lang.String");
总之,只要是在源程序中出现的类型,都有各自的Class实例对象。
二、反射机制概述
反射就是把Java类中的各种成分映射成相应的java类。JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
三、Constructor类
1、概述:Constructor类代表某个类中的一个构造方法
2、得到某个类所有的构造方法:
例子:Constructor [] constructors= Class.forName("java.lang.String").getConstructors();
3、得到某一个构造方法:通过要用到类型来获得对应的方法。
例子: Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);
4、创建实例对象:
通常方式:String str = new String(new StringBuffer("abc"));
反射方式: String str = (String)constructor.newInstance(new StringBuffer("abc"));
//调用获得的方法时要用到上面相同类型的实例对象
5、Class.newInstance()方法:该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
例子:String obj = (String)Class.forName("java.lang.String").newInstance();
四、Field类
1、概述:Field类代表某个类中的一个成员变量。
2、在访问类中的成员变量时,一定要注意的是当成员变量为私有变量时,直接使用getField( )是不能访问的,这时就需要使用暴力反射getDeclaredField( );并将该字段设置成为可处理状态 setAccessible(true);
3、获取类中的成员变量及暴力反射演示示例:
import java.lang.reflect*;
public class ReflectClass
{
public static void main(String[] args) throws Exception
{
ReflectPoint pt1 = new ReflectPoint(3, 5);
Field fieldy = pt1.getClass().getField("y");
/*
*
该怎么正确理解field_Y这个字段?这里的field_Y只是Filed类字节码身上的变量,并不是指对象.
我们可以创建很多个ReflectPoint类的对象而且每个对象都会有相应的field_Y字段,
也就是说该字段并不代表某个对象具体的值,只是一个变量.
而如果要拿出field_Y变量在某个对象身上的值那就用fieldY.get(具体的对象)
*/
System.out.println(fieldy.get(pt1));
//暴力反射,ReflectPoint中的x是私有的,按照上面fieldy的方法去获取是不可以的
//必须使用getDeclaredField();还要将fieldx设置成可访问的 setAccess(true)
Field fieldx = pt1.getClass().getDeclaredField("x");
fieldx.setAccessible(true);
System.out.println(fieldy.get(pt1));
}
}
class ReflectPoint
{
private int x;
public int y ;
public ReflectPoint(int x, int y)
{
super();
this.x = x;
this.y = y;
}
}
4、示例:运用反射获取来中的成员变量,将String类型的变量值中所有”b”换为”a”
import java.lang.reflect*;
public class ReflectClass
{
public static void main(String[] args) throws Exception
{
changeStringValue(pt1);
System.out.println(pt1);
}
//扫描下面方法ReflectPoint中所有String类型变量的值,如果值中有"b"则将改为"a"
private static void changeStringValue(Object obj) throws IllegalArgumentException, IllegalAccessException
{
//得到所有的字段
Field[] fields = obj.getClass().getFields();
//迭代所有的字段
for (Field field : fields)
{
//获得String类型的字段
//field.getType().equals(String.class) 字节码只有一份,比较时直接用"==",不用equals
if (field.getType() == String.class)
{
//获取传入对象中String类型的值
String oldValue = (String)field.get(obj);
//将这些值中有"b"的替换为"a"
String newValue = oldValue.replace("b", "a");
//将替换后的字段set给 原有对象
field.set(obj, newValue);
}
}
}
}
class ReflectPoint
{
private int x;
public int y ;
public String str1 = "ball";
public String str2 = "basketball";
public String str3 = "cat";
public ReflectPoint(int x, int y)
{
super();
this.x = x;
this.y = y;
}
//重写tostring
@Override
public String toString()
{
return str1 + "::"+ str2 + "::"+ str3;
}
}五、Method类
1、Method类代表某个类中 的一个成员方法。
2、得到类中的某一个方法:
Method charAt = ClassforName(“java.lang.String”)getMethod(“charAt”.int.class);
3、调用方法
通常方式:System.out.println(str.charAt(1));
反射方式:System.out.println(charAt.invoke(str,1));
注意:如果传递给Method对象的invoke()方法中第一个参数是null,说明该Method对象对应的是一个静态方法。
六、数组
1、具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象(具有相同的字节码)。
例:int[] a1 = new int[3]; int[] a2 = new int[5];
System.out.println(“a1.getClass() = a2.getClass()”); //输出为true。说明它们的字节码相同。
2、代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class。
基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用;非基本类型的一维数组,既可以当做Object类型使用,又可以当做Object[]类型使用。
int[] a1 = new int[3];
int[] a2 = new int[5];
int[][] a3 = new int[3][7];
String[] a4 = new String[5];
Object aObj = a1;
//Object[] aObj2 = a1; 是不可以的
Object[] aObj3 = a3;
Object[] aObj4 = a4;
3、Arrays类是对数组进行操作的工具,可以直接打印数组内容。对于字符串来说可以直接打印成字符串,但整型是不可以的。因为JDK1.4中Arrays.asList(Object[] a)传的是一个object数组,而整型不是,不适合JDK1.4语法,只适合JDK1.5中asList(T ...a)。但JDK1.5中传的是一个对象,因此打印出来的就是一个对象。
例: int[] a1 = new int[]{1,2,3;
String[] a4 = new String[]{“a”,”b”,”c“};
System.out.println(Arrays.asList(a1));
//结果:[[I@5bb77832]
System.out.println(Arrays.asList(a4));//结果:[a, b, c]
3136

被折叠的 条评论
为什么被折叠?



