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

反射机制

2015-10-12 14:20 465 查看

反射

能够分析“类”(不是对象)能力的程序称为反射(reflective)

运行中分析类的能力

运行中查看对象

实现通用的数组操纵代码

利用Method对象

Class 类

在程序运行期间,Java运行时系统始终为 所以对象维护一个 被称为运行时的类型标识。这个

信息跟踪着每个对象所属的类。虚拟机利用运行时类型信息选择相应的方法执行。

Object类中的
getClass()
方法将会返回一个Class类型的实例。

如下是源代码,该方法是一个不被允许重写的方法。

/**
* Returns the runtime class of this {@code Object}. The returned
* {@code Class} object is the object that is locked by {@code
* static synchronized} methods of the represented class.
*
* <p><b>The actual result type is {@code Class<? extends |X|>}
* where {@code |X|} is the erasure of the static type of the
* expression on which {@code getClass} is called.</b> For
* example, no cast is required in this code fragment:</p>
*
* <p>
* {@code Number n = 0;                             }<br>
* {@code Class<? extends Number> c = n.getClass(); }
* </p>
*
* @return The {@code Class} object that represents the runtime
*         class of this object.
* @see    Class Literals, section 15.8.2 of
*         <cite>The Java™ Language Specification</cite>.
*/
public final native Class<?> getClass();


三种获得* 类类型 *实例 的方法

Object object = new Test();
System.out.println(object.getClass().getName());  // 将会输出 yang.Test (yang是我的包名字)

String className = "java.util.Date";
Class c1 = Class.forName(className);    // 获得当前类类型信息

Class c1 = Date.class;


一个
Class
对象实际上表示的是一个类型,而这个类型未必一定是一种类。例如:
int.class


虚拟机为* 每种类型(基本类型到每一个类)* 管理一个
Class
对象

Class c = int.class
c = Enum.class
c = void.class
c = boolean.class
c = double.class
c = float.class
c = Float.class
c = new Float(3.4F).getClass
c = Class.forName("java.awt.Button")

public @interface Ann {
}

c = Ann.class;
// 类型:从基本类型、甚至 void 、boolean类型到数组 int[] 到类到接口到枚举enum到注解都是类型,每种类型都有一个Class对象维护信息。
//我们不可以访问这个对象(因为是私有的),它是由虚拟机生成的,引用这个对象方式非常多(如上)。
// <基类和子类是两种类型>有两个Class对象。


if(e.getClass() == EObject.class)   //判断对象`e`是不是`EObject`类类型的对象


利用反射分析类的能力

java.lang.reflect


Field Method Constructor
分别用于描述类的域、方法、构造器

public class ReflectionTest
{
public static void main(String[] args)
{
// read class name from command line args or user input
String name;
if (args.length > 0) name = args[0];
else
{
Scanner in = new Scanner(System.in);
System.out.println("Enter class name (e.g. java.util.Date): ");
name = in.next();
}
try
{
// print class name and superclass name (if != Object)
Class cl = Class.forName(name);
Class supercl = cl.getSuperclass();
String modifiers = Modifier.toString(cl.getModifiers());
if (modifiers.length() > 0) System.out.print(modifiers + " ");
System.out.print("class " + name);
if (supercl != null && supercl != Object.class) System.out.print(" extends "
+ supercl.getName());    // Java是单进程方式,所以“实现接口”不算继承方法,只算一种多态性质。

Sy
4000
stem.out.print("\n{\n");
printConstructors(cl);
System.out.println();
printMethods(cl);
System.out.println();
printFields(cl);
System.out.println("}");
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
System.exit(0);
}
public static void printConstructors(Class cl)
{
Constructor[] constructors = cl.getDeclaredConstructors();
for (Constructor c : constructors)
{
String name = c.getName();
System.out.print("   ");
String modifiers = Modifier.toString(c.getModifiers());
if (modifiers.length() > 0) System.out.print(modifiers + " ");
System.out.print(name + "(");
// print parameter types
Class[] paramTypes = c.getParameterTypes();
for (int j = 0; j < paramTypes.length; j++)
{
if (j > 0) System.out.print(", ");
System.out.print(paramTypes[j].getName());
}
System.out.println(");");
}
}
public static void printMethods(Class cl)
{
Method[] methods = cl.getDeclaredMethods();
for (Method m : methods)
{
Class retType = m.getReturnType();
String name = m.getName();
System.out.print("   ");
// print modifiers, return type and method name
String modifiers = Modifier.toString(m.getModifiers());
if (modifiers.length() > 0) System.out.print(modifiers + " ");
System.out.print(retType.getName() + " " + name + "(");
// print parameter types
Class[] paramTypes = m.getParameterTypes();
for (int j = 0; j < paramTypes.length; j++)
{
if (j > 0) System.out.print(", ");
System.out.print(paramTypes[j].getName());
}
System.out.println(");");
}
}
public static void printFields(Class cl)
{
Field[] fields = cl.getDeclaredFields();
for (Field f : fields)
{
Class type = f.getType();
String name = f.getName();
System.out.print("   ");
String modifiers = Modifier.toString(f.getModifiers());
if (modifiers.length() > 0) System.out.print(modifiers + " ");
System.out.println(type.getName() + " " + name + ";");
}
}
}


复制数组的好方法

public static Object[] badCopyOf(Object a[], int newLength) {
Object[] newArray = new Object[newLength]; // 一个对象数组无法转换成实际对象数组

// 设有数组 A[] array = new A[10];
// array是一对象(类型为数组,元素类型为A)
// Object[] arrayTemp = (Object[]) array; // 这是可以的
// Object arrayT = (Object) array; // 可以
// 上述也可以转回去,我们始终要关注 new 的实际对象是谁(反射是最好的查看机制)。

// 阿猫阿狗(Object)都可以看家,但这个家究竟是谁的?利用反射机制。

System.arraycopy(a, 0, newArray, 0, Math.min(a.length, newLength));
return newArray;  // 转不会原始实际数组对象类型
}

/**
* A good method of Array copy
* @param a
* @param newLength
* @return
*/
public static Object goodCopyOf(Object a, int newLength) {
Class<?> c = a.getClass();
if(!c.isArray()) return null;
Class<?> componentType = c.getComponentType(); // Returns the Class representing the component type of an array.
int length = Array.getLength(a);
Object newArray = Array.newInstance(componentType, newLength);
System.arraycopy(a, 0, newArray, 0, Math.min(length, newLength));
return newArray;
}


实例

public static void main(String[] args) {
Object object = new Object[10];
if(object.getClass().isArray()) {
Object[] objects = (Object[]) object;
for(int i=0; i<objects.length; i++){
objects[i] = "Fuck you!";
}
for (Object objStr : objects) {
if(objStr.getClass() == String.class){
System.out.println(objStr.toString());
}
// 或者
//                System.out.println(objStr);
}
}

public class Test{
public static void main(String[] args) {
Object object = new Object[10];
if(object.getClass() == String[].class) {    // 条件不成立
Object[] objects = (Object[]) object;
for(int i=0; i<objects.length; i++){
objects[i] = "Fuck you!";
}
for (Object objStr : objects) {
//                if(objStr.getClass() == String.class){
//                    System.out.println(objStr.toString());
//                }
//                // 或者
System.out.println(objStr);
}
}

}

public static void main(String[] args) {
Object object = new Object[10];
if(object.getClass() == Object[].class) {    // 可以的
Object[] objects = (Object[]) object;
for(int i=0; i<objects.length; i++){
objects[i] = "Fuck you!";
}
for (Object objStr : objects) {
//                if(objStr.getClass() == String.class){
//                    System.out.println(objStr.toString());
//                }
//                // 或者
System.out.println(objStr);
}
}

}


Java独特的方法调用机制(不太好,容易出错)

public class Test{
public static void main(String[] args) {
try {
Method out = Test.class.getMethod("out", String.class);
out.invoke(new Test(), "OK men and girls");
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}

}

public void out(String str){
System.out.println(str);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java