JAVA_反射

一.Class类

1.class类的简介

      在面向对象中,万事万物皆对象!其实在JAVA语言中,有两样东西不是面向对象的,一个是普通的数据类型(int a=5),它用封装类(包装类)来弥补了!另外一个是静态的成员变量,他是一个类!可是类也是对象,所以一般在JAVA中认为万事万物皆对象!    

      那么又有一个问题了!类的对象又是什么呢?

      类是java.lang.Class的实例对象!

      这又产生了一个问题了,这个Class类又如何表示呢?这就引出了下面这个标题,class类的使用!

2.class类的使用

package com.liangdianshui;

public class UseClass {

    public static void main(String[] args) {

        /**
         * 问题1.MyClass的实例对象如何表示呢?
         * 直接new出来就能表示了
         */
        MyClass myclass=new MyClass();
        
        /**
         * MyClass这个类也是一个实例对象,它是java.lang.Class类的实例对象
         * 问题2.那么,java.lang.Class类的实例对象又是如何表示的呢?
         * 任何一个类都是java.lang.Class类的实例对象,这个实例对象有三种表示的方式
         */
        //第一种表示方式(这也告诉我们任何一个类都有一个隐含的静态成员变量)
        Class c1=MyClass.class;   //知道类名的时候使用
        //第二种表示方式:通过getClass方法获取
        Class c2=myclass.getClass();  //知道类对象的时候使用
        //第三种表示的方式:
        Class c3=null;
        try {
            c3=Class.forName("com.liangdianshui.MyClass");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        System.out.println(c1==c2);
        System.out.println(c2==c3);
        
        
        /**
         * 上面的c1,c2和c3我们可以称之为类类型(class type)
         * 因此我们也可以得知:我们可以通过类的类类型来创建该类的对象实例!
         * 也就是说:我们可以通过c1,c2和c3来创建MyClass类的实例对象! 
         */
        try {
            MyClass myclass2 = (MyClass) c1.newInstance(); //前提是MyClass类要有无参数的构造函数(构造方法)
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

// 创建一个类
class MyClass {
     
    public MyClass(){
        System.out.println("liangdianshui");
    }
}
运行结果:

liangdianshui
true
true
liangdianshui

3.动态加载类

      上面提到的表示Class类的三种实例方法的其中一种是Class.forName("类的名称"),其实这种方法不仅表示了类的类类型(也就是表示Class类的实例对象)还代表了动态的加载类!然而JAVA在编译的时候是加载静态加载类的,运行的时刻是加载动态加载类的!

实例:

package com.liangdianshui;

public class Office {

    public static void main(String[] args) {

        try {
            // 动态加载类,在运行的时候才加载(功能性的类一般使用动态加载类)
            Class c = Class.forName(args[0]);
            OfficeAble officeAble = (OfficeAble) c.newInstance();
            officeAble.start();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

创建一个接口封装公共的方法!

package com.liangdianshui;

interface OfficeAble {
    public void start();
}
具体的实例来实现接口!
package com.liangdianshui;

public class World implements OfficeAble{

    @Override
    public void start() {
        // TODO Auto-generated method stub
        System.out.println("World");
    }

}
package com.liangdianshui;

public class Excel implements OfficeAble {

    @Override
    public void start() {
        // TODO Auto-generated method stub
        System.out.println("Excel");
    }

}

4.类类型

        基本的数据类型是类类型,void等关键字也是类类型

证明上面结论的demo:

package com.liangdianshui;

public class ClassType {
    public static void main(String[] args) {
        
        Class classInt=int.class; //int类的类类型
        Class classString=String.class; //String类的类类型
        Class classDouble=double.class;
        Class classVoid=void.class;   //void关键字的类类型
        
        System.out.println(classInt.getName()); //获取类名
        System.out.println(classString.getName()); //获取类名
        System.out.println(classString.getSimpleName()); //获取不包含包名的类名(单一类名)
        System.out.println(classVoid.getName());
    }
}
运行的结果:

int
java.lang.String
String
void

二.方法的反射,成员变量的反射,构造函数的反射

1.通过反射获取类的信息

package com.liangdianshui.reflect.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.TypeVariable;

public class ClassUtil {

    static StringBuilder sb = null;

    /**
     * 获取类的名称
     * 
     * @param obj
     *            该对象所属类的信息
     * @return 类名
     */
    public static String getClassMsg(Object obj) {
        sb = new StringBuilder();
        Class c = obj.getClass();// c是obj类的类类型
        sb.append(c.getName()); // 获取类名
        return sb.toString();
    }

    /**
     * 获取该类中所有public函数的信息
     * Methods类,是方法的对象,一个成员方法就是一个Method对象
     * 1.getMethod():获取该类中所有的public的函数,包括父类继承而来的函数
     * 2.getDeclaredMethods():获取的是该类自己声明的方法
     * @param obj  该对象所属类的信息
     * @return  String 方法类型+" "+方法名+"("+"参数名"+")" 
     */
    public static String getMethods(Object obj) {
        sb = new StringBuilder();
        Class c = obj.getClass();
        Method[] methods = c.getMethods(); // 过去该类中的所有public函数
        for (Method method : methods) {
            Class returnType = method.getReturnType(); // 获取方法的返回类型
            sb.append(returnType.getName());
            sb.append(" ");
            sb.append(method.getName() + "(");
            Class[] parameterTypes = method.getParameterTypes();
            if (parameterTypes.length == 0) {
                sb.append(")");
                sb.append("\n");
                continue;
            }
            for (int i = 0; i < parameterTypes.length; i++) {
                sb.append(parameterTypes[i].getName());
                if (i == parameterTypes.length - 1) {
                    sb.append(")");
                    continue;
                }
                sb.append(",");
            }
            sb.append("\n");
        }
        return sb.toString();
    }
    
    /**
     * 获取该类成员变量的信息
     * 1.成员变量也是对象,它是java.lang.reflect.Field的对象,Filed类封装了关于成员变量的信息
     * 2.getFields():获取所有public的成员变量的信息
     * 3.getDeclaredFields():获取该类自己声明的成员变量的信息
     * @param obj 该对象所属类 
     * @return
     */
    public static String getFiled(Object obj) {
        sb = new StringBuilder();
        Class c = obj.getClass();
        Field[] fields = c.getDeclaredFields();
        for (Field field : fields) {
            sb.append(field.getName());
            sb.append("\n");
        }
        return sb.toString();
    }
    
    /**
     * 获取构造函数的信息
     * 1.getConstructors():获取所有public构造函数的信息
     * 2.getDeclaredConstructors():获取自定义的构造函数的信息
     * @param obj
     * @return
     */
    public static String getConstructor(Object obj) {
        sb = new StringBuilder();
        Class c = obj.getClass();
        Constructor[] constructors = c.getDeclaredConstructors();
        for (Constructor Constructor : constructors) {
            sb.append(Constructor.getName());
            sb.append("(");
            Class[] typeParameters = Constructor.getParameterTypes();
            if (0 == typeParameters.length) {
                sb.append(")");
                sb.append("\n");
                continue;
            }
            for (int i = 0; i < typeParameters.length; i++) {
                sb.append(typeParameters[i].getName());
                if (i == typeParameters.length - 1) {
                    sb.append(")");
                    continue;
                }
                sb.append(",");
            }

            sb.append("\n");
        }
        return sb.toString();
    }
}

package com.liangdianshui;

import com.liangdianshui.reflect.util.ClassUtil;

public class PrintMsg {
    public static void main(String[] args) {
        String str = "Hello";
        System.out.println("str的类名为:" + ClassUtil.getClassMsg(str));
        System.out.println("str的类中的所有public函数:\n" + ClassUtil.getMethods(str));
        System.out.println("str类中自定义成员变量的信息:\n"+ClassUtil.getFiled(str));
        System.out.println("str类中自定义的构造函数:\n"+ClassUtil.getConstructor(str));
    }
}
运行结果:
str的类名为:java.lang.String
str的类中的所有public函数:
boolean equals(java.lang.Object)
java.lang.String toString()
int hashCode()
int compareTo(java.lang.Object)
int compareTo(java.lang.String)
int indexOf(java.lang.String,int)
int indexOf(int)
int indexOf(int,int)
int indexOf(java.lang.String)
java.lang.String valueOf(float)
java.lang.String valueOf(double)
java.lang.String valueOf(boolean)
java.lang.String valueOf([C,int,int)
java.lang.String valueOf([C)
java.lang.String valueOf(java.lang.Object)
java.lang.String valueOf(char)
java.lang.String valueOf(int)
java.lang.String valueOf(long)
char charAt(int)
int codePointAt(int)
int codePointBefore(int)
int codePointCount(int,int)
int compareToIgnoreCase(java.lang.String)
java.lang.String concat(java.lang.String)
boolean contains(java.lang.CharSequence)
boolean contentEquals(java.lang.StringBuffer)
boolean contentEquals(java.lang.CharSequence)
java.lang.String copyValueOf([C,int,int)
java.lang.String copyValueOf([C)
boolean endsWith(java.lang.String)
boolean equalsIgnoreCase(java.lang.String)
java.lang.String format(java.util.Locale,java.lang.String,[Ljava.lang.Object;)
java.lang.String format(java.lang.String,[Ljava.lang.Object;)
[B getBytes()
[B getBytes(java.lang.String)
void getBytes(int,int,[B,int)
[B getBytes(java.nio.charset.Charset)
void getChars(int,int,[C,int)
java.lang.String intern()
boolean isEmpty()
int lastIndexOf(int)
int lastIndexOf(int,int)
int lastIndexOf(java.lang.String,int)
int lastIndexOf(java.lang.String)
int length()
boolean matches(java.lang.String)
int offsetByCodePoints(int,int)
boolean regionMatches(int,java.lang.String,int,int)
boolean regionMatches(boolean,int,java.lang.String,int,int)
java.lang.String replace(char,char)
java.lang.String replace(java.lang.CharSequence,java.lang.CharSequence)
java.lang.String replaceAll(java.lang.String,java.lang.String)
java.lang.String replaceFirst(java.lang.String,java.lang.String)
[Ljava.lang.String; split(java.lang.String)
[Ljava.lang.String; split(java.lang.String,int)
boolean startsWith(java.lang.String)
boolean startsWith(java.lang.String,int)
java.lang.CharSequence subSequence(int,int)
java.lang.String substring(int,int)
java.lang.String substring(int)
[C toCharArray()
java.lang.String toLowerCase()
java.lang.String toLowerCase(java.util.Locale)
java.lang.String toUpperCase(java.util.Locale)
java.lang.String toUpperCase()
java.lang.String trim()
void wait(long,int)
void wait(long)
void wait()
java.lang.Class getClass()
void notify()
void notifyAll()

str类中自定义成员变量的信息:
value
hash
serialVersionUID
serialPersistentFields
CASE_INSENSITIVE_ORDER
HASHING_SEED
hash32

str类中自定义的构造函数:
java.lang.String([B)
java.lang.String([B,int,int)
java.lang.String([B,java.nio.charset.Charset)
java.lang.String([B,java.lang.String)
java.lang.String([B,int,int,java.nio.charset.Charset)
java.lang.String(int,int,[C)
java.lang.String([C,boolean)
java.lang.String(java.lang.StringBuilder)
java.lang.String(java.lang.StringBuffer)
java.lang.String([I,int,int)
java.lang.String([C,int,int)
java.lang.String([C)
java.lang.String(java.lang.String)
java.lang.String()
java.lang.String([B,int,int,java.lang.String)
java.lang.String([B,int)
java.lang.String([B,int,int,int)

2.方法的反射操作

(1)通过上面获取类的信息可以获取某个类中的某个方法的信息,所以我们可以通过method.invoke()来实现方法的反射操作,在这之前,我们需要获取这个方法!

(2)1.要获取一个方法先要获取类的信息

           2.通过getMethod()获取方法(会抛异常,避免此方法不存在)

           3.method.invoke()来实现方法的反射操作

实例:

先创建一个类

package com.liangdianshui;

public class PrintfA {

    public void printfA(int a, int b) {
        System.out.println(a + b);
    }

    public void printfA(String a, String b) {
        System.out.println(a + b);
    }
}
然后通过类名获取PrintfA的类类型,并实例化!然后获取printfA的方法,通过invoke()来实现方法的反射操作

package com.liangdianshui;

import java.lang.reflect.Method;

public class MethodReflect {

    public static void main(String[] args) {
        Class c = PrintfA.class;
        PrintfA printfA;
        try {
            printfA = (PrintfA) c.newInstance();
            Method method = c.getMethod("printfA", int.class, int.class);
            method.invoke(printfA, 10, 11);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}


Demo:http://download.csdn.net/detail/two_water/9449782


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值