java 反射

Class

java 为每一个对象实例都维护了一个Class类,虚拟机使用这个对象来跟踪对象所属的类

Tips:
RTTI(Run-Time Type Identification)运行时类型识别。这种技术实现了多态的概念。而这种技术在Java中是通过Class 来实现的。

如何获得class呢?

  1. getClass();
    Object(所有类的父类)有一个getClass可以获得Class对象
  2. Class.forName();
    静态方法可以传入一个字符串来初始化class类,如java.util.Date
  3. T.class T是任意类型如
    Class c1=String.class;
        Class c2=int.class;
        Class c3=Double [].class;

可以使用Class来判断对象所属的类


        if(new String().getClass()==String.class){}
        //或者
        if(new String() instanceof String)

Class类中的一些方法

我们可以使用class.newinstance()方法来实例化一个对象。



        try {
            String s=(String) Class.forName("java.lang.String").newInstance();
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

TIps:

newinstance只能调用默认的构造函数,如果没有默认函数会抛出异常

反射

反射是什么?通过反射我们可以知道一个类中有什么从而动态初始化类。例如下面的例子可以打印一个类中的成员。代码来自《java 核心技术》

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.sql.Date;
import java.util.Scanner;

public class Test {
    String s;

    public  static void main(String [] args){

        Scanner in=new Scanner(System.in);

        System.out.println("Pease input a class name for  whcih you wanna looking  ");
        String classname=in.nextLine();

         try {

             Class c= Class.forName(classname);

             String modifier=Modifier.toString(c.getModifiers());

             if(modifier.isEmpty()!=true) System.out.print(modifier+" ");

             System.out.println(c);

             Class superc=c.getSuperclass();

             if(superc!=null&&superc!=Object.class)System.out.print("extends"+superc.getName());

             System.out.print("{\n");

             printConstructor(c);
             System.out.println();
             printmethods(c);
             System.out.println();
             printFileds(c);
             System.out.print("\n}");


        } catch (SecurityException | ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }





    }





    private static void printFileds(Class c) {
        // TODO Auto-generated method stub

        Field[] fs=c.getFields();

        for(Field f:fs){

            System.out.print("  ");
            String modifier=Modifier.toString(f.getModifiers());
            System.out.print(modifier+" ");
            System.out.println(f.getName());


        }




    }





    private static void printmethods(Class c) {
        // TODO Auto-generated method stub

        Method [] ms=c.getMethods();



        for(Method m: ms){
            String name=m.getName();
            System.out.print("  ");

            String modifier=Modifier.toString(m.getModifiers());
            System.out.print(modifier+" ");
            System.out.print(name+"(");
            Class[] cs=m.getParameterTypes();

            for( int j=0;j<cs.length;j++){
                if(j>0)System.out.print(",");
                System.out.print(cs[j].getName());



            }

            System.out.println(");");






        }
    }





    private static void printConstructor(Class c) {
        // TODO Auto-generated method stub
        Constructor[] constructors=c.getConstructors();


        for(Constructor cons: constructors){
            String name=cons.getName();
            System.out.print("  ");

            String modifier=Modifier.toString(cons.getModifiers());
            System.out.print(modifier+" ");
            System.out.print(name+"(");
            Class[] cs=cons.getParameterTypes();

            for( int j=0;j<cs.length;j++){
                if(j>0)System.out.print(",");
                System.out.print(cs[j].getName());


            }

            System.out.println(");");



        }


    }


}

从上面代码案例我们可以知道,想要得到一个对象的全部信息,首先要得到它的Class对象。之后就可以从Class对象中提取它的Filed,Method,Constructor对象。我们就可以用如下方法来工作了。
getxxx():返回所有共有方法或属性
getdeclaredxxx():返回所有属性和方法
getdeclaringClass()
逆向找到方法/属性所属的Class
getExceptionTypes()
返回方法抛出的异常
getReturnType
返回方法返回的类型
getmodifier()
放回访问修饰符

Modifier类中有很多静态方法isxxx()来判断有没有某一种访问修饰符。也可以用toString()直接输出访问修饰符。

注意:

getDeclaredxxx()方法可一返回私有域。但是因为java 的安全机制我们是不能查看其中的值的。

User u=new User();
Filed f=u.class.getDeclaredFiled("name")
Object o=f.get(U);
//请注意get方法的使用

因为name是User的私有域, 所以我们是不可以访问的。会爆出一个illegalAccessException。但是我们可以修改默认的安全机制使其可以读取私有域中的值。只需要调用Filed,Method,Constructor对象setAccessible(true).

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值