《Java高级-反射API:Class类的使用(5种)》

一、想对你说


(1)之前一直有小伙伴让我总结下Java相关的知识点,这里我针对有一定Java基础的同学做了一个系列的总结,感兴趣的同学可以看看顶部的【Java专栏】希望对大家有所帮助。
(2)要是对您有所帮助的话,可以给 “大大大钢琴” 点个赞,这是我继续下去的动力,谢谢大家了!废话不多说了,直接上干货。

二、反射API:Class类

(一)获取Class类

其它API接口在第二个【代码块】中

import java.lang.reflect.Constructor;

public class test_demo {
    public static void main(String[] args) throws ClassNotFoundException {

        //获取class对象方法(这里使用的是String类)
        String str1 = "abc";
        Class cls1 = str1.getClass();
        Class cls2 = String.class;
        Class cls3 = Class.forName("java.lang.String");
        System.out.println(cls1);
        System.out.println(cls1 == cls2);
        System.out.println(cls1 == cls3);

        //案例1:获取class对象方法
        try {
            Class<?> demo = Class.forName("Person");
            Constructor<?> cons[] = demo.getConstructors(); //取得全部的构造函数
            Person per1 = (Person) cons[0].newInstance(20);
            Person per2 = (Person) cons[1].newInstance("大大大钢琴");
            Person per3 = (Person) cons[2].newInstance();
            System.out.println(per1);
            System.out.println(per2);
            System.out.println(per3);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

//定义一个类,用于反射中的调用
class Person {
    private String name;
    private int age;
    public Person() {}
    public Person(String name) { this.name = name;}
    public Person(int age) { this.age = age; }
    public String getName() { return name;}
    @Override
    public String toString() {
        return "[" + this.name + "  " + this.age + "]";
    }
}

//**********方法**********
//    forName(String classname)
//    该方法返回给定串名相应的Class对象。
//    getClassLoader()
//    获取该类的类装载器。
//    getComponentType()
//    如果当前类表示一个数组,则返回表示该数组组件的Class对象,否则返回null。
//    getConstructor(Class[])
//    返回当前Class对象表示的类的指定的公有构造子对象。
//    getConstructors()
//    返回当前Class对象表示的类的所有公有构造子对象数组。
//    getDeclaredConstructor(Class[])
//    返回当前Class对象表示的类的指定已说明的一个构造子对象。
//    getDeclaredConstructors()
//    返回当前Class对象表示的类的所有已说明的构造子对象数组。
//    getDeclaredField(String)
//    返回当前Class对象表示的类或接口的指定已说明的一个域对象。
//    getDeclaredFields()
//    返回当前Class对象表示的类或接口的所有已说明的域对象数组。
//    getDeclaredMethod(String,Class[])
//    返回当前Class对象表示的类或接口的指定已说明的一个方法对象。
//    getDeclaredMethods()
//    返回Class对象表示的类或接口的所有已说明的方法数组。
//    getField(String)
//    返回当前Class对象表示的类或接口的指定的公有成员域对象。
//    getFields()
//    返回当前Class对象表示的类或接口的所有可访问的公有域对象数组。
//    getInterfaces()
//    返回当前对象表示的类或接口实现的接口。
//    getMethod(String,Class[])
//    返回当前Class对象表示的类或接口的指定的公有成员方法对象。
//    getMethods()
//    返回当前Class对象表示的类或接口的所有公有成员方法对象数组,包括已声明的和从父类继承的方法。
//    getModifiers()
//    返回该类或接口的Java语言修改器代码。
//    getName()
//    返回Class对象表示的类型(类、接口、数组或基类型)的完整路径名字符串。
//    getResource(String)
//    按指定名查找资源。
//    getResourceAsStream(String)
//    用给定名查找资源。
//    getSigners()
//    获取类标记。
//    getSuperclass()
//    如果此对象表示除Object外的任一类,那么返回此对象的父类对象。
//    isArray()
//    如果Class对象表示一个数组则返回true,否则返回false。
//    isAssignableFrom(Class)
//    判定Class对象表示的类或接口是否同参数指定的Class表示的类或接口相同,或是其父类。
//    isInstance(Object)
//    此方法是Java语言instanceof操作的动态等价方法。
//    isInterface()
//    判定指定的Class对象是否表示一个接口类型。
//    isPrimitive()
//    判定指定的Class对象是否表示一个Java的基类型。
//    newInstance()
//    创建类的新实例。
//    toString()
//    将对象转换为字符串。

(二)Class.isPrimitive()判断是否是基本类型的字节码

Class.isPrimitive()判定指定的Class对象是否表示一个Java的基类型(boolean、char、byte、short、int、long、float、double)。


public class test_demo {
    public static void main(String[] args) throws ClassNotFoundException {

        //Class.isPrimitive()判定指定的Class对象是否表示一个Java的基类型(boolean、char、byte、short、int、long、float、double)。
        //方案1:判断是否是基本类型的字节码
        String str = "abc";
        Class cls1 = str.getClass();
        Class cls2 = String.class;
        Class cls3 = null;//必须要加上null
        try {
            cls3 = Class.forName("java.lang.String");
            System.out.println(cls1==cls2);
            System.out.println(cls1==cls3);
            System.out.println(cls1.isPrimitive());
            System.out.println(int.class.isPrimitive());//判定指定的 Class 对象是否表示一个基本类型。
            System.out.println(int.class == Integer.class);
            System.out.println(int.class == Integer.TYPE);
            System.out.println(int[].class.isPrimitive());
            System.out.println(int[].class.isArray());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        //方案2:判断是否是基本类型的字节码
        Class stringClass=String.class;
        System.out.println("String is primitive type:"+stringClass.isPrimitive());
        Class booleanClass=Boolean.class;
        System.out.println("Boolean is primitive type:"+booleanClass.isPrimitive());
    }
}

(三)Class.forName()返回一个类

forName(String className)

forName(String className, boolean initialize, ClassLoader loader)
1.loader指定装载参数类所用的类装载器,如果null则用bootstrp装载器。
2.initialize=true时,肯定连接,而且初始化了;
3.initializ=false时,绝对不会初始化,但是可能被连接了,但是这里有个例外,如果在调用这个forName()前,已经被初始化了,那么返回的类型也肯定是被初始化的(当然,这里也暗含着:被同一个loader所装载的,而且这个类被初始化了)


public class test_demo {
    public static <ExampleInterface> void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        //案例1:forName(String className)
        //借鉴地址:http://www.51gjie.com/java/779.html
        String className = "Person";
        Class aClass = Class.forName(className);
        ExampleInterface factory = (ExampleInterface)aClass.newInstance();
        System.out.println(factory);
    }
}

//定义一个类,用于反射中的调用
class Person {
    private String name;
    private int age;
    public Person() {}
    public Person(String name) { this.name = name;}
    public Person(int age) { this.age = age; }
    public String getName() { return name;}
    @Override
    public String toString() {
        return "[" + this.name + "  " + this.age + "]";
    }
}

(四)Class.getField()/getDeclaredField()返回成员变量

Class.getField()返回已加载类声明的所有public成员变量的Field对象,包括从父类继承过来的成员变量,参数name指定成员变量的名称。

Class.getDeclaredField()返回当前类所有成员变量。

import java.lang.reflect.*;

public class test_demo {

    public Object testobj;
    public String testString;
    public static void main(String[] args) throws Exception {
        test_demo field = new test_demo();
        Class cl = field.getClass();
        Field fobj = cl.getField("testobj");
        Field fString = cl.getDeclaredField("testString");

        //1、通过使用getField()方法是获取类的公共字段(这里用的是当前test_demo类)
        System.out.println("Field: " + fobj.toString());

        //2、通过使用getDeclaredField()方法是获取
        System.out.println("DeclaredField: " + fString.toString());
    }
}

(五)Class.getMethod()/getDeclaredMethods返回Method对象

Class.getMethod():获取当前类及所有继承的父类的public修饰的方法。仅包括public

Class.getDeclaredMethod():获取当前类的所有方法,包括public/private/protected/default修饰的方法。


import java.lang.reflect.*;

public class test_demo {
    public static void main(String[] args) throws Exception {
        try {

            //方法的字符串
            test_demo testObj = new test_demo();
            testObj.say("大大大钢琴");
            Class testClass = testObj.getClass();
            //(1)参数为null
            Method lMethod = testClass.getDeclaredMethod("say", null);
            System.out.println("method = " + lMethod.toString());
            //(2)直接传入类对象
            Method lMethod1 = testClass.getDeclaredMethod("say", String.class);
            System.out.println("method = " + lMethod1.toString());
            //(3)将类对象封装在数组中传入
            Class[] cArg = new Class[1];
            cArg[0] = String.class;
            Method lMethod2 = testClass.getDeclaredMethod("say", cArg);
            System.out.println("method = " + lMethod2.toString());
        } catch(NoSuchMethodException e) {
            System.out.println(e.toString());
        }
    }
    public String name = "hello,china!";
    public String say() {
        return "hello,seo";
    }
    protected void say(String name) {
        System.out.println("Hello! " + "My name is " + name);
        this.name = name;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大大大钢琴

喜欢!就请他吃3块钱好吃的吧!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值