- import java.lang.reflect.Array;
- import java.lang.reflect.Constructor;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import java.util.Arrays;
-
-
-
-
-
-
-
- public class ReflectTest {
- @SuppressWarnings("unchecked")
- public static void main(String[] args) throws Exception {
-
-
-
-
-
-
-
-
- System.out.println("==========Class类Demo========");
- Class<? extends Object> cla1 = String.class;
- Class<? extends Object> cla2 = Class.forName("java.lang.String");
-
-
-
- System.out.println("两对象是否相等:" + (cla1 == cla2));
-
-
-
- System.out.println("是否是原始类型:" + cla1.isPrimitive());
- System.out.println("int 是否是原始类型?:" + int.class.isPrimitive());
- System.out.println("原始类型及其包装类型字节码:" + (Integer.class == int.class));
-
-
-
- System.out.println(int.class == Integer.TYPE);
-
-
-
- System.out.println("原始类型的数组的字节码不是原始类型:" + (int[].class.isPrimitive()));
- System.out.println("数组是否为Array类型:" + int[].class.isArray());
-
- System.out.println("=====================反射中构造方法demo=================");
-
-
-
- Constructor[] constructors = StringBuffer.class.getConstructors();
- for (Constructor constructor : constructors) {
- System.out.println(constructor.getName());
- }
-
-
-
- Constructor constructor = String.class
- .getConstructor(StringBuffer.class);
- System.out.println(constructor.getName());
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- String str = (String) constructor.newInstance(new StringBuffer("demo"));
- System.out.println("根据Constructor的newInstance方法所创建的实例:" + str);
- System.out.println("str的第二个字符:" + str.charAt(1));
-
- System.out.println("=============成员变量的反射============");
- ReflectPoint pp1 = new ReflectPoint(3, 5);
- Field fieldY = pp1.getClass().getField("y");
-
-
-
- System.out.println("FieldY:" + fieldY);
-
-
-
- System.out.println("fieldY的值:" + fieldY.get(pp1));
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Field fieldX = pp1.getClass().getDeclaredField("x");
- fieldX.setAccessible(true);
- System.out.println("FieldX:" + fieldX);
- System.out.println("fieldX的值:" + fieldX.get(pp1));
-
- System.out.println("===========Medthod类===============");
- Method methodCharAt = String.class.getMethod("charAt", int.class);
- System.out.println(methodCharAt);
-
-
-
- String methodStr = "HelloWorld!";
- System.out.println(methodCharAt.invoke(methodStr, 1));
-
- System.out.println("============数组的反射==============");
- int[] arr1 = new int[] { 45, 5, 6, 666, 778 };
- System.out.println(arr1.getClass().getSuperclass());
- int[] arr11 = new int[] { 1, 2, 3 };
-
-
-
- System.out.println("arr1==arr11:" + (arr1 == arr11));
- System.out.println("arr1.getClass()==arr11.getClass():"
- + (arr1.getClass() == arr11.getClass()));
- int[][] arr2 = new int[][] { new int[] { 1, 2, 3, 4, 5 },
- new int[] { 6, 7, 8, 9, 10 } };
- System.out.println("arr2:" + arr2);
- String[] arr3 = new String[] { "hello", "world" };
- System.out.println("arr3:" + arr3);
-
-
-
-
- System.out.println(arr2.getClass().getSuperclass());
- System.out.println("String superClass:"
- + arr3.getClass().getSuperclass().getName());
-
- Object[] obj2 = arr2;
- Object[] obj3 = arr3;
-
-
-
-
- System.out.println(obj2);
- System.out.println(obj3);
- System.out.println("=============java.util.Arrays类==========");
-
-
-
-
-
-
-
- System.out.println(Arrays.asList(arr1));
- System.out.println(arr1.getClass().getName());
- System.out.println(Arrays.asList(obj3));
-
- Object printObj = arr3;
- Class clazz = printObj.getClass();
- if (clazz.isArray()) {
-
-
- System.out.println("传入的参数是数组");
- int length = Array.getLength(printObj);
- for (int i = 0; i < length; i++) {
- System.out.println(Array.get(printObj, i));
- }
- } else {
- System.out.println("传入的参数不是数组");
- System.out.println(printObj);
- }
- }
- }
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* 浅谈Java反射
*
* @author leejon
*
*/
public class ReflectTest {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws Exception {
/**
* 反射的概念: 反射就是把Java类中的各种成分映射成相应的Java类 。
* 例如:一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包 等信息
* 也用一个个的Java类来表示。就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。
* 表示Java类的Class类显然要提供一系列的方法来获取其中的变量,方法,构造方法,修饰符,包等信息。 这些信息用相应类的实例对象来表示。
* 他们就是Field,Method,Constructor,Package等。
* 一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示, 通过调用Class类的方法可以得到这些实例对象。
*/
System.out.println("==========Class类Demo========");
Class<? extends Object> cla1 = String.class;
Class<? extends Object> cla2 = Class.forName("java.lang.String");
/**
* 之所以相等。是因为在jvm中已经装载了String类对象的字节码
*/
System.out.println("两对象是否相等:" + (cla1 == cla2));
/**
* String类不属于原始类型
*/
System.out.println("是否是原始类型:" + cla1.isPrimitive());
System.out.println("int 是否是原始类型?:" + int.class.isPrimitive());
System.out.println("原始类型及其包装类型字节码:" + (Integer.class == int.class));
/**
* 基本类型的字节码==其包装类的TYPE属性的字节码
*/
System.out.println(int.class == Integer.TYPE);
/**
* 数组不属于原始类型,是为另外一种类型:Array
*/
System.out.println("原始类型的数组的字节码不是原始类型:" + (int[].class.isPrimitive()));
System.out.println("数组是否为Array类型:" + int[].class.isArray());
System.out.println("=====================反射中构造方法demo=================");
/**
* 获取某个类的所有的构造函数,返回一个Constructor类型的数组
*/
Constructor[] constructors = StringBuffer.class.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor.getName());
}
/**
* 根据参数的类型获取某个类的构造函数
*/
Constructor constructor = String.class
.getConstructor(StringBuffer.class);
System.out.println(constructor.getName());
/**
* 注意:创建对象的时候指定的参数类型要和获取该Constructor对象时的类型相同
* 如果类型不同,在IDE中可以通过编译,但是运行期则会抛出异常,----类型不匹配
* 假设:constructor.newInstance(new StringBuffer("demo"));
* 则运行异常,因为String.class.getConstructor(StringBuffer.class)
* 获取Constructor实例时指定的参数类型为StringBuffer
* =============================================================
* ××××××要注意的地方:××××××××调用获得的方法时要用相同的类型×××××××××××××
* =============================================================
*
* Class类的newInstance和Constructor对象的newInstance的关系:
* Class类的newInstance方法为创建类的对象提供便利。
* 一般情况下,创建对的对象步骤:class-->Constructor-->newIntance(Class<?>...paramType)
* Class.newInstance():该方法内部先得到默认的构造方法,然后用该构造方法创建实例。/
* 内部代码用到了缓存机制来保存默认构造方法的实例对象
*/
String str = (String) constructor.newInstance(new StringBuffer("demo"));
System.out.println("根据Constructor的newInstance方法所创建的实例:" + str);
System.out.println("str的第二个字符:" + str.charAt(1));
System.out.println("=============成员变量的反射============");
ReflectPoint pp1 = new ReflectPoint(3, 5);
Field fieldY = pp1.getClass().getField("y");
/**
* fieldY不表示某个对象代表的值,而单纯表示对象本身
*/
System.out.println("FieldY:" + fieldY);
/**
* 如果要获取fieldY在具体对象上的值(字段的值)则:fieldY.get(OneObj)
*/
System.out.println("fieldY的值:" + fieldY.get(pp1));
/**
* 对于私有的成员变量,不能使用getField获得, 所以,以下代码运行时出错
*/
// Field fieldX = pp1.getClass().getField("x");
// System.out.println("FieldX:" + fieldX);
// System.out.println("fieldX的值:"+fieldX.get(pp1));
/**
* 对于私有的成员属性,可以采用getDeclaredField("属性名")的方式获取该成员(Filed)的引用
* 并且要设置其为可访问:如:fieldX.setAccessible(true); 该访问成员的方式可称之为暴力反射^_^
* ========================================================
* 对于这里的fieldX和上面的fieldY,仅仅代表字节码的对象, 而不是表示某个对象中的一个成员属性的值
* 如果要将其和某个对象相关联起来,则可以使用:fieldX.get(pp1),表示在pp1这个对象中x这个属性的值
* ========================================================
*/
Field fieldX = pp1.getClass().getDeclaredField("x");
fieldX.setAccessible(true);
System.out.println("FieldX:" + fieldX);
System.out.println("fieldX的值:" + fieldX.get(pp1));
System.out.println("===========Medthod类===============");
Method methodCharAt = String.class.getMethod("charAt", int.class);
System.out.println(methodCharAt);
/**
* 以反射的方式调用某个对象的方法 用:invoke(要调用那个对象,参数数组): 后面的参数方法原型为可变长度参数,其内部以数组形式实现。
*/
String methodStr = "HelloWorld!";
System.out.println(methodCharAt.invoke(methodStr, 1));
System.out.println("============数组的反射==============");
int[] arr1 = new int[] { 45, 5, 6, 666, 778 };
System.out.println(arr1.getClass().getSuperclass());
int[] arr11 = new int[] { 1, 2, 3 };
/**
* 这里比较的是两个对象,所以不相等。而下面的getClass则比较的是字节码。 因为两个数组都是int型的, 所以,他们的字节码是相等的。
*/
System.out.println("arr1==arr11:" + (arr1 == arr11));
System.out.println("arr1.getClass()==arr11.getClass():"
+ (arr1.getClass() == arr11.getClass()));
int[][] arr2 = new int[][] { new int[] { 1, 2, 3, 4, 5 },
new int[] { 6, 7, 8, 9, 10 } };
System.out.println("arr2:" + arr2);
String[] arr3 = new String[] { "hello", "world" };
System.out.println("arr3:" + arr3);
/**
* 基本类型的一维数组只可以被当作Object使用而不能被当作Object[]来使用。
* 非基本类型的一维数组,既可以作为Oject类型来使用,也可以作为Object[]类型来使用
*/
System.out.println(arr2.getClass().getSuperclass());
System.out.println("String superClass:"
+ arr3.getClass().getSuperclass().getName());
// Object[] obj1=arr1;(编译器报错)
Object[] obj2 = arr2;
Object[] obj3 = arr3;
/**
* 以下两行显示[[I@14318bb<br>
* [Ljava.lang.String;@ca0b6
*/
System.out.println(obj2);
System.out.println(obj3);
System.out.println("=============java.util.Arrays类==========");
/**
* 对于字符串类型的数组。用Arrays的静态方法asList(Object...a)能够将obj2作为一个List集合将其值输出,
* 但是,对于int类型的数组,虽然转换成为了List,却还是输出其每个元素的地址,这是为什么呢?
* 因为arr1数组是int型,属于基本类型。arr1
* .getClass().getName()=[I,所以JDK编译器将整个数组作为一个Object(一个整型数组)进行处理.
* 这也是Arrays.asList(Object...a)处理int[]和String[]时的差异
*/
System.out.println(Arrays.asList(arr1));
System.out.println(arr1.getClass().getName());
System.out.println(Arrays.asList(obj3));
/** 对数组进行反射操作 */
Object printObj = arr3;
Class clazz = printObj.getClass();
if (clazz.isArray()) {
/** 如果是数组 */
/** 得到长度 */
System.out.println("传入的参数是数组");
int length = Array.getLength(printObj);
for (int i = 0; i < length; i++) {
System.out.println(Array.get(printObj, i));
}
} else {
System.out.println("传入的参数不是数组");
System.out.println(printObj);
}
}
}
- public class ReflectPoint {
- private int x;
- public int y;
-
- public ReflectPoint(int x, int y) {
- this.x = x;
- this.y = y;
- System.out.println("X:" + this.x + ",Y:" + this.y);
- }
-
- @Override
- public String toString() {
- return "X:" + this.x + ",Y:" + this.y;
- }
- }