Class类

来源:互联网 发布:数据库分析工具 编辑:程序博客网 时间:2024/05/22 11:31

万事万物皆对象

先看一段代码:

public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException{        //String类的实例        String str = new String();        //String其实也是一个实例对象 它是Class类的实例        //任何类的Class的实例对象有三种获取方式        //第一种 每个类都有一个隐含的静态成员变量class        Class c1 = String.class;        //第二种 通过该类的getClass方法获取        Class c2 = str.getClass();        //第三种 Class.forName()        Class c3 = Class.forName("java.lang.String");        System.out.println(c1 == c2 & c2 == c3);        //c1 c2 c3叫做class type 可以通过类类型创建类的实例        String st = (String) c1.newInstance();    }

java.lang.Class

所有的类都是java.lang.Class类的实例
万事万物皆对象,类也是个实例化的对象。

类的加载

静态加载

new的对象都是在编译时对类进行加载

String str = new String();

动态加载

在运行时对类进行加载

String st = (String) c1.newInstance();

使用场景

在静态加载类的时候如果代码中某一个类不存在,就会报错,如果运用动态加载就会解决这个问题,

1 问题场景 当Word存在Excel不存在的时候 就会报错
public class Office {    public static void main(String[] args)  {        if("Word".equals(args[0]))        {            Word w = new Word();            w.start();        }        if("Excel".equals(args[0]))        {            Excel e = new Excel();            e.start();        }    }}
2 用动态加载解决该问题
public class OfficeBetter {    public static void main(String[] args) throws Exception  {        Class c = Class.forName(args[0]);        OfficeAble of = (OfficeAble)c.newInstance();        of.start();    }}//通用接口public interface OfficeAble {    public void start();}//Word 类public class Word implements OfficeAble {    public  void start()    {        System.out.println("World is started!");    }}

这里写图片描述

获取方法信息

/**     * 打印类的信息,包括类的成员变量、成员函数     *      * @param args     */    public static void printClassInfo(Object obj) {        // 获取类信息 要先获取类类型        Class c = obj.getClass();        // 获取类名称        System.out.println("c类名称:" + c.getName());        /*         * 获取类方法 Method类是方法类 getMethods()获取的是所有public的方法 包括父类继承而来的         * getDeclaredMethods()获取的是该类自己声明的所有方法 不问访问权         */        Method[] m1 = c.getMethods();        Method[] m2 = c.getDeclaredMethods();        for (Method m : m1) {            // 方法的名称            System.out.println("方法的名称:" + m.getName());            // 方法的返回类型的类类型            Class returnType = m.getReturnType();            System.out.println("返回类型的类类型:" + returnType);            System.out.println("返回类型的类类型的名字:" + returnType.getName());            // 获取参数类型的类类型            Class[] paramTypes = m.getParameterTypes();            for (Class p : paramTypes) {                // 参数的名称                System.out.println("参数名:" + p.getName());            }        }    } 

获取成员变量&构造函数

    /**     * 打印类的信息,包括类的成员变量、成员函数     *      * @param args     */    static void printFieldInfo(Object obj) {        Class c = obj.getClass();        /*         * 成员变量也是对象         * java.lang.reflect.Field         * Field封装了了关于成员变量的操作         * getFields() 获取所有public的成员变量         * getDeclaredFields() 获取所有该类声明的成员变量         */        Field[] fList =  c.getDeclaredFields();        for(Field f : fList)        {            //得到成员变量的类型的类类型            Class fType = f.getType();            System.out.println("成员变量类型的类类型:" + fType.getName());            //得到成员变量的名称            String fName =f.getName();            System.out.println("成员变量名:" + fName);        }    }
    /**     * 打印类的信息,包括类的构造函数     *      * @param args     */    static void printConInfo(Object obj) {        Class c = obj.getClass();        /*         * 构造函数也是对象         * java.lang.Constructor 封装了了关于构造函数的操作         * getFields() 获取所有public的成员变量         * getDeclaredFields() 获取所有该类声明的成员变量         */        Constructor[] conList =  c.getConstructors();        for(Constructor con : conList)        {            //得到构造函数的类型的类类型            Class conType = con.getClass();            System.out.println("成员变量类型的类类型:" + con.getName());            //得到构造函数的入参            Class[] pType=con.getParameterTypes();            for(Class p :pType)            {                //入参的类类型                System.out.println("入参的类类型:" + p.getName());            }        }    }

方法的反射

public class MethodDemo {    public static void main(String[] args) {        // 要获取print(int ,int )方法 1.要获取一个方法就是获取类的信息,获取类的信息首先要获取类的类类型        A a1 = new A();        Class c = a1.getClass();        /*         * 2.获取方法 名称和参数列表来决定 getMethod获取的是public的方法 getDelcaredMethod自己声明的方法         */        try {            Method m = c.getDeclaredMethod("print", int.class, int.class);            Method m1 = c.getDeclaredMethod("print", new Class[] { int.class, int.class });            // 方法的反射操作            // a1.print(10, 20);方法的反射操作是用m对象来进行方法调用 和a1.print调用的效果完全相同            a1.print(10, 9);            Object o1 = m.invoke(a1, new Object[] { 10, 9 });            Object o2 = m1.invoke(a1, 10, 9);            // 方法如果没有返回值返回null,有返回值返回具体的返回值            // 获取方法print(String,String)            // 用方法进行反射操作        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}class A {    public void print() {        System.out.println("helloworld");    }    public void print(int a, int b) {        System.out.println(a + b);    }    public void print(String a, String b) {        System.out.println(a.toUpperCase() + "," + b.toLowerCase());    }}

通过反射了解集合泛型的本质

public class ClassFanXing {    public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException,            IllegalArgumentException, InvocationTargetException {        ArrayList list = new ArrayList();        ArrayList<String> list1 = new ArrayList<String>();        Class c = list.getClass();        Class c1 = list1.getClass();        list1.add("hello");        // list1.add(1);        System.out.println(c == c1);        // 反射的操作都是编译后的操作        // c==c1返回结果是true 是为了防止输错 只在编译阶段有效        // 验证 我们可以通过方法的反射来绕过编译        Method m = c1.getMethod("add", Object.class);        m.invoke(list1, 100);        System.out.println(list1.size());        System.out.println(list1);    }}

结果

true2[hello, 100]
原创粉丝点击