java反射

反射:

1. 概述:

  1. 反射机制有什么用:

    通过java语言中的反射机制可以读和修改字节码文件。

  2. 反射机制的相关类在哪个包下:java.lang.reflect.*;

  3. 反射机制相关的类有哪些:

    java.lang.class;   //代表整个字节码,代表一个类型。代表整个类。
    java.lang.reflect.Method;  //代表字节码中的方法字节码。代表类中的方法
    java.lang.reflect.Constructor;  //代表字节码中的构造方法字节码。代表类中的构造方法
    java.lang.reflect.Field; //代表字节码中的属性字节码。代表类中的成员变量(静态变量+实例变量)
    

2. 获取Class的三种方式:

1. 第一种方式:

            /*
            * Class.forName()
            *  1.静态方法
            *  2.方法的参数是一个字符串
            *  3.字符串需要的是一个完整类名
            *  4.完整类名必须带有包名。java.lang包也不能省略。
            * */
            Class c1=Class.forName("java.lang.String"); //c1代表String类型
            Class c2=Class.forName("java.util.Date"); //c2代表Date类型
            Class c3=Class.forName("java.lang.Integer");//c3代表Integer类型
            Class c4=Class.forName("java.lang.System");// c4代表System类型

2. 第二种方式:

/*
       * 第二种方式:java中任何一个对象都有一个方法:getClass()
      * */
         String s="abc";
         Class x=s.getClass(); //x代表String.class字节码文件。x代表String类型
         System.out.println(c1==x);//true(==判断的是对象的内存地址)

3.第三种方式:

        /*
        * 第三种方式:java语言中任何一个类型,包括基本数据类型,它都有class属性
        * */

        Class z=String.class; //z代表String类型
        Class k= Date.class;//k代表Date类型
        Class f=int.class;//f代表int类型
        System.out.println(x==z); //true

4.总结:

/*
* 获取class的三种方式
* 第一种:Class c=Class.forName("完整类名加包名");
* 第二种:Class c=对象。getClass();
* 第三种:Class c=任何类型.class;
* */

3. 通过反射实例化对象:

  1. idea获取类名:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AwoORetB-1596363357479)(C:\Users\user\Desktop\java分析图\获取类名.png)]

  2. 通过Class的newInstance()方法来实例化对象。newInstance()方法内部实际上调用了无参数构造方法,必须保证无参构造存在才可以。 不然会出现 ”实例化“ 异常。

    public class User {
        public User() {
            System.out.println("无参数构造方法");
        }
    }
    
    
    
    public class ReflectTest02 {
        public static void main(String[] args) {
            //通过反射机制获取class,通过Class来实例化对象
            try {
                Class c=Class.forName("com.ma.bean.User"); //c代表User对象
    
                //newInstance() 这个方法会调用User这个类的无参数构造方法,完成对象的创建
                //重点newInstance()调用的无参构造,必须保证无参构造是存在的
                Object obj=c.newInstance();//com.ma.bean.User@282ba1e
                System.out.println(obj);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
        }
    }
    

1.反射机制的灵活运用:

  1. 新建一个属性配置文件classinfo.properties,里面写上:
className=com.ma.bean.User
  1. 通过FileReader读取文件内容,并创建对应属性对象:
/*
*
* 验证反射机制的灵活性
* java代码写过一遍之后,在不改变java源代码的基础之上,可以做到不同对象的实例化
* 非常之灵活(符合OCP开闭原则)
* */
public class ReflectTest03 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException {
        //这种方式代码是写死的,只能创建一个User类型对象
        //User u=new User();


        //以下代码是灵活的,代码不需要改动,只需修改配置文件,就可以创建不同的实例对象
        //通过io流,读取文件
        FileReader reader=new FileReader("java反射/classinfo.properties");

        //创建属性类对象
        Properties pro=new Properties(); //key value都是String

        //加载
        pro.load(reader);

        //关闭流
        reader.close();

        //通过key获取value
        String className=pro.getProperty("className");
        System.out.println(className); //com.ma.bean.User

        //通过反射机制实例化对象
        Class c=Class.forName(className);
        System.out.println(c); //class com.ma.bean.User
        Object obj=c.newInstance();
        System.out.println(obj); //com.ma.bean.User@64c64813
        }
}

  1. 这样在不修改原代码的基础上,通过修改属性配置文件classinfo.properties中的className属性,就可以达到创建不同对象的目的,非常之灵活(符合OCP开闭原则)。

2. 理解forName():

  1. Class.forName()发生了什么:

    如果你只需要一个类的静态代码块执行,其他代码一律不执行,你可以使用Class.forName(“完整类型”),这个方法的执行会导致类加载,类加载时,静态代码执行,并且只执行一次。后面一些框架的原理与之相关。

  2. 代码演示:

/*
* 研究一下:Class.forName()发生了什么
* 重点:如果你只需要一个类的静态代码块执行,其他代码一律不执行,你可以使用
* Class.forName("完整类型"),这个方法的执行会导致类加载,类加载时,静态代码执行
* */
public class ReflectTest04 {
    public static void main(String[] args) {
        try {
            //Class.forName()这个方法的执行会导致类加载
            Class.forName("com.ma.reflect.Myclass");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}


class Myclass{
    // 静态代码块在类加载时执行,并且只执行一次
    static{
        System.out.println("MyClass类的静态代码块执行了");
    }
}

4. 有关文件路径:

1.分析以下方式的路径缺点:

FileReader reader=new FileReader("java反射/classinfo.properties");

​ 移植性差,在IDEA中默认的当前路径是project的根,这个代码假设离开了IDEA,换到了其他位置,可能当前路径就不是project的根了,这时这个路径就无效了。

2. 解决方式一:

  • 接下来说一种比较通用的一种路径,即使代码换位置了,这样编写仍然是通用的。用以下通用方式的前提是:这个文件必须在类的路径下。
  • 什么是类路径:凡是在src下的都是类路径下。 src是类的根路径。从类的根路径作为起点开始
  • 代码如下:
  /*
        * 解释:
        * Thread.currentThread() :当前线程对象
        * getContextClassLoader():是线程对象的方法,可以获取到当前线程的类加载器对象。
        * getResource():【获取资源】这是类加载器的方法,当前线程的类加载器默认从类的根路径下加载资源。
        * getPath():路径
        */

        String path=Thread.currentThread().getContextClassLoader().
                getResource("className.properties").getPath();
        System.out.println(path);//D:/javase进阶/out/production/java反射/className.properties

        //获取db.properties文件下的绝对路径。
        String path1=Thread.currentThread().getContextClassLoader().
            getResource("com/ma/bean/db.properties").getPath();
        System.out.println(path1); //D:/javase进阶/out/production/java反射/com/ma/bean/db.properties

3. 代码改进:

  1. 直接以流的形式返回:getResourceAsStream():
public class IoPropertiesTest {
    public static void main(String[] args) throws IOException {
/*        String path=Thread.currentThread().getContextClassLoader().
                getResource("className.properties").getPath();
        FileReader reader=new FileReader(path);*/

        //直接以流的形式返回
        InputStream reader=Thread.currentThread().getContextClassLoader().
                getResourceAsStream("className.properties");
        Properties pro=new Properties();
        pro.load(reader);
        reader.close();

        //通过key获取value
        String className=pro.getProperty("className");
        System.out.println(className);  //com.ma.bean.User
    }
}

4. 解决方式二:

  1. 资源绑定器(ResourceBundle):

    java.util包下提供了一个资源绑定器,便于获取属性配置文件中的内容。使用以下这种方式的时候,文件扩展名必须是properties,属性配置文件xxx.properties必须放到类路径下,在写路径的时候,路径后面的扩展名不用写(.properties)。

  2. 代码如下:

/*
* java.util包下提供了一个资源绑定器,便于获取属性配置文件中的内容。
* 使用以下这种方式的时候,属性配置文件xxx.properties必须放到类路径下。
* */
public class ResourceBundleTest {
    public static void main(String[] args) {
        //资源绑定器,只能绑定xxx.properties文件,并且这个文件必须在类路径下。
        //在写路径的时候,路径后面的扩展名不能写。
        ResourceBundle bundle=ResourceBundle.getBundle("className");
        
        String className=bundle.getString("className");
        System.out.println(className);
        
    }
}

5. 类加载器概述:

  1. 什么是类加载器:

    专门负责加载类的命令或工具。 ClassLoader。

  2. JDK中自带了3个类加载器:

    • 启动类加载器:
    • 扩展类加载器:
    • 应用类加载器:
  3. 假设有这样的一段代码:

String s="abc";

代码在开始执行之前,会将所需要的类全部加载到JVM当中。通过类加载器加载,看到以上代码,类加载器会找String.class文件,找到就加载。首先通过 “启动类加载器” 加载。 启动类加载器专门加载 ” jre\lib\rt.jar“,rt,jar中都是JDK最核心的类库。

如果通过 ”启动类加载器“ 加载不到的时候,会通过 ”扩展类加载器“ 加载。 扩展类加载器专门加载 ”jre\lib\ext*.jar“

如果通过 “扩展类加载器” 加载不到的时候,会通过 “应用类加载器” 加载。 应用类加载器专门加载 classpath中的jar包(class文件)。

6. 双亲委派机制:

  1. 概述:java 中为了保证类加载的安全,使用了双亲委派机制,优先从启动类加载器中加载,我们称为 “父”,“父” 无法加载到,再从扩展类加载器中加载,这个称为 “母”,双亲委派。 如果都加载不到,才会考虑从应用类加载器中加载,直到加载为止。

7. 反射Field:

1. 获取Field:

  1. 用的方法:
 String getName(); //获取完整类名
 String getSimpleName(); //获取简类名
 Field[] getFields(); //获取类中所有的public修饰的Field 
 Field[] getDeclaredFields(); //获取所有的Field
 int getModifiers(); //获取属性修饰符,返回的修饰符是一个数字,每个数字是修饰符的代号。
 String toString();//将修饰符代号数字转化为字符串  
 Class<?> getType(); //获取属性的类型
 String getName(); //获取属性的名字  
  
  1. 代码演示:
// 反射属性Field
public class Student {
    //Field 翻译为字段 其实就是属性/成员
    // 4个Field 分别采用了不同的访问控制权限修饰符
   public int no;  //public  int no  整个Field对象。
   private String name;
   protected int age;
   boolean sex;
   public static final double MATH_PI=3.1415926;
}




/*
* 反射Student类当中所有的 Field
* */
public class ReflectTest05 {
    public static void main(String[] args) throws ClassNotFoundException {
        // 获取整个类
        Class studentClass=Class.forName("com.ma.bean.Student");

        String className=studentClass.getName();
        System.out.println("完整类名:"+className); //com.ma.bean.Student

        String simpleName=studentClass.getSimpleName();
        System.out.println("简类名:"+simpleName);  //Student
        // 获取类中所有的public修饰的Field   Field[] getFields()
        Field[]fields= studentClass.getFields();
        System.out.println(fields.length);  //1

        //取出这个元素
        Field f=fields[0];
        //取出这个Field它的名字
        String fieldName=f.getName();
        System.out.println(fieldName); //no

        // 获取所有的Field
        Field[] fs=studentClass.getDeclaredFields();
        System.out.println(fs.length); //4
        System.out.println("===============================");

        //遍历
        for (Field field:
             fs) {
            //获取属性修饰符
            int i=field.getModifiers(); //1 返回的修饰符是一个数字,每个数字是修饰符的代号。
            //如何将这个代号数字转化为字符串
            String modifierString=Modifier.toString(i);
            System.out.println(modifierString);

            // 获取属性的类型
           // System.out.println(field.getType().getSimpleName());

            // 获取属性的名字
           // System.out.println(field.getName());

            System.out.println(field.getType().getSimpleName()+":"+field.getName());
        }


    }
}

2.反编译Field:

  1. 通过以上方法反编译Student类的属性:
/*
* 通过反射机制,反编译一个类的属性
* */
public class ReflectTest06 {
    public static void main(String[] args) throws Exception {
        //创建这个是 为了拼接字符串
        StringBuilder s=new StringBuilder();
        Class studentClass=Class.forName("com.ma.bean.Student");

        s.append(Modifier.toString(studentClass.getModifiers())+" class "+ studentClass.getSimpleName()+"{\n");
        Field[]fields=studentClass.getDeclaredFields();
        for (Field field:fields){
            s.append("\t");
            s.append(Modifier.toString(field.getModifiers()));
            s.append(" ");
            s.append(field.getType().getSimpleName());
            s.append(" ");
            s.append(field.getName());
            s.append(";\n");
        }

        s.append("}");
        System.out.println(s);

    }
}

3. 通过反射机制访问对象属性:

  1. 需要的方法:
 Object get(Object obj); // 返回指定对象上此 Field 表示的字段的值。
 void set(Object obj, Object value);  //将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
 Field getDeclaredField(String name); //根据属性名称获取Field 
 setAccessible(boolean flag); //打破封装,可访问私有属性
  1. 代码演示:
/*
* 怎么通过反射机制访问一个java对象的属性,
*  给属性赋值set
*  获取属性的值get
* */
public class ReflectTest07 {
    public static void main(String[] args) throws Exception {
        //不使用反射机制赋值
        Student s=new Student();
        s.no=1111;  //三要素:1.Student对象s  2.no属性   3. 值 111
        System.out.println(s.no);



        //使用反射机制
        Class studentClass =Class.forName("com.ma.bean.Student");
        Object obj=studentClass.newInstance(); //student对象(低层调用无参数构造方法)

        //获取no属性(根据属性名称获取Field)
        Field noField= studentClass.getDeclaredField("no");
        System.out.println(noField.getName()); //no

        //给Student对象obj的no属性赋值
        /*
        *虽然使用了反射机制,但是三要素还是缺一不可
        * 要素1:Student对象obj
        * 要素2:no属性 noField
        * 要素3:222值
        * 注意:反射机制虽然让代码复杂了,但是为了一个 “灵活”,这也是值得的
        * */
        noField.set(obj,222); // 给obj对象的no属性赋值222

        //获取属性的值
        System.out.println(noField.get(obj)); //obj
        
        
         //可以访问私有的属性嘛
        Field nameField=studentClass.getDeclaredField("name");
        //打破封装 (反射机制缺点:打破封装,会出现安全隐患)
        //这样设置完之后在外部也是也可以访问private的
        nameField.setAccessible(true);
        //给name属性赋值
        nameField.set(obj,"xiaoma");
        //获取name属性值
        System.out.println(nameField.get(obj));
    }
}

8. 反射机制Method:

1. 介绍:

  1. 可变长参数: int… args 。语法:类型… 参数名(一定是三个点)。
  2. 注意:
    • 可变参数要求参数的个数是:0-N个。
    • 可变长度参数在参数列表中必须在最后一个位置上,而且可变长度参数只能有一个。
    • 可变长度参数可以当一个数组来看待。
  3. 代码演示:
/*
* 可变长参数: int... args
* 语法:类型... (注意一定是三个点)
*
* 1. 可变参数要求参数的个数是:0-N个。
* 2. 可变长度参数在参数列表中必须在最后一个位置上,而且可变长度参数只能有一个
* 3. 可变长度参数可以当一个数组来看待。
* */
public class ArgsTest {
    public static void main(String[] args) {
        m();
        m(10);
        m(10,22);
        m3("abc","ab","de");
        //传一个数组进去
        String[]strs={"a","b","c"};
        m3(strs);

        m3(new String[]{"我","是","小","马"});
    }


    public static void m(int... args){
        System.out.println("m方法执行了");
    }

    //报错
    //public static void m2(String...args1,int...arg2){}

    // 必须在最后,只能有1个
    public static void m2(int a,String...args){}

    public static void m3(String...args){
        //args有length属性,说明args是一个数组
        //可以将可变长度参数当做一个数组来看
        for (int i=0;i<args.length;i++){
            System.out.println(args[i]);
        }
    }

}

2.反射Method:

  1. 需要的方法
 Method[] getDeclaredMethods(); //获取所有的Method,包括私有的,但不包括继承方法
 int getModifiers();//获取修饰符列表 
 Class<?> getReturnType(); //获取返回值类型
 String getName(); //获取方法名
 Class<?>[] getParameterTypes(); //获取方法参数  
  1. 代码演示:
/*
* 作为了解内容
* 反射Method
* */
public class ReflectTest08 {
    public static void main(String[] args) throws Exception {
        // 获取类
        Class userServiceClass=Class.forName("com.ma.Service.UserService");
        // 获取所有的Method(包括私有的)
        Method[]methods=userServiceClass.getDeclaredMethods();
        //System.out.println(methods.length); //2

        //遍历Method
        for (Method method:
           methods  ) {
            // 获取修饰符列表
            System.out.println(Modifier.toString(method.getModifiers()));
            // 获取方法的返回值类型
            System.out.println(method.getReturnType().getSimpleName());
            //获取方法名
            System.out.println(method.getName());
            // 方法的参数(一个方法的参数可能会有多个。)
            Class[]parameterTypes=method.getParameterTypes();
            for (Class parameterType:
                 parameterTypes) {
                System.out.println(parameterType.getSimpleName());
            }
        }

    }
}

3. 反编译Method:

/*
* 反编译 Method
* */
public class ReflectTest09 {
    public static void main(String[] args) throws Exception {
        StringBuilder s=new StringBuilder();

        Class userServiceClass = Class.forName("com.ma.Service.UserService");
        s.append(Modifier.toString(userServiceClass.getModifiers())+"class"+userServiceClass.getSimpleName()+ "{\n");
        Method[]methods= userServiceClass.getDeclaredMethods();
        for (Method method:
             methods) {
            s.append("\t");
            s.append(Modifier.toString(method.getModifiers()));
            s.append(" ");
            s.append(method.getReturnType().getSimpleName());
            s.append(" ");
            s.append(method.getName());
            s.append("(");
            //参数
            Class[]paramerTypes=method.getParameterTypes();
            for (Class paramerType:
                 paramerTypes) {
                s.append(paramerType.getSimpleName());
                s.append(",");
            }
            //删除指定下标位置上的字符
            s.deleteCharAt(s.length()-1);
            s.append("){}\n");
        }

        s.append("}");
        System.out.println(s);
    }
}

4. 反射机制调用方法:

  1. 反射机制,让代码很具有通用性可变化的内容都是写到配置文件当中的,将来修改配置文件之后,创建的对象就不一样了,调用的方法也不同了,但是java代码不需要,做任何改动,这就是反射机制的魅力。重点:必须掌握,通过反射机制怎么调用一个对象的方法
  2. 用到的方法:
 Method getDeclaredMethod(String name, Class<?>... parameterTypes); //获取method,返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。

 Object invoke(Object obj, Object... args); //调用方法  对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。 
 

3.代码演示:

/*
* 用户业务类
* */
public class UserService {

    /**
     *
     * @param name 用户名
     * @param password  密码
     * @return true:登录成功   false:登录失败
     */
    public boolean login(String name,String password){
        if ("admin".equals(name) && "123".equals(password)){
            return true;
        }
        return false;
    }



    /*
    * 退出系统方法
    * */
    public void logout(){
        System.out.println("系统已经安全退出");
    }
}

/*
*
* 重点:必须掌握,通过反射机制怎么调用一个对象的方法。
*
* 反射机制,让代码很具有通用性,可变化的内容都是写到配置文件当中的,将来
* 修改配置文件之后,创建的对象就不一样了,调用的方法也不同了,但是java代码不需要
* 做任何改动,这就是反射机制的魅力。
* */
public class ReflectTest10 {
    public static void main(String[] args) throws Exception {
        // 不使用反射机制,怎么调用方法
        // 创建对象
        UserService userService=new UserService();
        boolean loginSuccess=userService.login("admin","123");
        System.out.println(loginSuccess?"登录成功":"登录失败");

        // 使用反射机制调用一个对象的方法该怎么做
        Class userServiceClass = Class.forName("com.ma.Service.UserService");

        // 创建对象
        Object obj=userServiceClass.newInstance();

        //获取method
        //不能只通过方法名来确定方法,可能也会出现重载
        //java中依靠方法名和参数列表区分一个方法
        Method loginMethod=userServiceClass.getDeclaredMethod("login", String.class, String.class);

        //调用方法
        /*
        * 要素1 : 对象userService
        * 要素2 : login方法名
        * 要素3 : 实参列表
        * 要素4 : 返回值
        * */

        //invoke :调用 必须记住
        /*
         * 四要素:
         * loginMethod方法,
         * obj对象,
         * "admin","123"实参
         * retValue 返回值
         *
        *
        * */
        Object retValue=loginMethod.invoke(obj,"admin","123");
        System.out.println(retValue);


    }
}

9. 反射Constructor:

1. 反编译Constructor:

  1. 需要的方法:
 Constructor<?>[] getConstructors();  //返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。
 int getModifiers(); //以整数形式返回此 Constructor 对象所表示构造方法的 Java 语言修饰符。
 Class<?>[] getParameterTypes(); //按照声明顺序返回一组 Class 对象,这些对象表示此 Constructor 对象所表示构造方法的形参类型。  
  1. 代码演示:
/*
* 反编译一个类的Constructor 构造方法
* */
public class ReflectTest11 {
    public static void main(String[] args) throws Exception {
        StringBuilder s=new StringBuilder();
        Class vipClass=Class.forName("com.ma.bean.Vip");
        s.append(Modifier.toString(vipClass.getModifiers())+" class "+vipClass.getSimpleName()+" {\n");
        // 拼接构造方法
        Constructor[]constructors=vipClass.getConstructors();
        for (Constructor constructor:
             constructors) {
            s.append("\t");
            s.append(Modifier.toString(constructor.getModifiers()));
            s.append(" ");
            s.append(vipClass.getSimpleName());
            s.append("(");
            //拼接参数
            Class[]parameterTypes=constructor.getParameterTypes();
            for (Class parameterType:
                 parameterTypes) {
                s.append(parameterType.getSimpleName());
                s.append(",");

            }
            // 删除最后下标位置上的字符
            if(parameterTypes.length>0) {
                s.deleteCharAt(s.length() - 1);
            }
            s.append("){}\n");
        }
        s.append("}");
        System.out.println(s);
    }
}

2. 反射机制调用构造方法创建对象:

  1. 用到的方法:
Constructor<T> getConstructor(Class<?>... parameterTypes); //返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。

  1. 代码演示:
/*
* 重要
*
* */
public class ReflectTest12 {
    public static void main(String[] args) throws Exception {
        //不使用反射机制如何创建对象
        Vip v1=new Vip();
        Vip v2=new Vip(110,"zhangsan","2001-10-11",true);

        //使用反射机制怎么创建对象
        Class c=Class.forName("com.ma.bean.Vip");

        //调用无参数构造方法
        Object obj=c.newInstance();
        System.out.println(obj);

        //调用有参数的构造方法。
        //第一步:先获取到这个有参数的构造方法
        Constructor con=c.getDeclaredConstructor(int.class,String.class,String.class,boolean.class);
        //第二步:调用构造方法创建对象
        Object newobj=con.newInstance(110,"xiaoma","1997-09-30",true);
        System.out.println(newobj);

        //调用无参数构造方法
        Constructor nocon=c.getDeclaredConstructor();
        Object noObj=nocon.newInstance();
        System.out.println(noObj);

    }
}

10. 获取父类和父接口:

  1. 需要的新方法:
 Class<? super T> getSuperclass(); //获取父类
 Class<?>[] getInterfaces();  //获取类所实现的所有接口
  1. 代码演示:
/*
* 重点:给你一个类,怎么获取这个类的父类,已经实现了哪些接口
* */
public class ReflectTest13 {
    public static void main(String[] args) throws Exception {
        //String 举例
        Class c=Class.forName("java.lang.String");

        //获取String的父类
        Class superClass=c.getSuperclass();
        System.out.println(superClass.getName()); //java.lang.Object

        //获取String类实现的所有接口(一个类可以实现多个接口)
        Class[]interfaces=c.getInterfaces();
        for (Class in:
            interfaces ) {
            System.out.println(in.getName());
        }
    }
}

  1. 代码演示:
/*
* 重点:给你一个类,怎么获取这个类的父类,已经实现了哪些接口
* */
public class ReflectTest13 {
    public static void main(String[] args) throws Exception {
        //String 举例
        Class c=Class.forName("java.lang.String");

        //获取String的父类
        Class superClass=c.getSuperclass();
        System.out.println(superClass.getName()); //java.lang.Object

        //获取String类实现的所有接口(一个类可以实现多个接口)
        Class[]interfaces=c.getInterfaces();
        for (Class in:
            interfaces ) {
            System.out.println(in.getName());
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值