反射面试专题

134 阅读4分钟

我们将从以下常见问题进行讲解说明

  1. 除了 new创建对象以外,还有什么方式创建对象?
  2. Java反射创建对象效率高还是通过new创建对象的效率高?
  3. 什么是反射?
  4. 哪里用得到反射机制?
  5. 获取Class对象有哪些方式
  6. java反射核心类
  7. 反射的优缺点
  8. 如何使用java的反射

除了 new创建对象以外,还有什么方式创建对象?

反射可以创建对象,一个是Class类的newInstance(调用的只能是无参),一个是java.lang.relect.Constructor类里也有一个newInstance(可以是有参,可以是私有)。当然还有其他方式,也来简单说说。

1.我们调用一个对象的clone()方法,此时jvm会帮助我们生成一个新的对象,并将对象的内容都拷贝到新对象上去,此时不会调用类的构造方法。要使用该方法我们必须要实现Cloneable接口,并且重写clone方法

public class Person implements Cloneable {
	...
	// 访问权限写为public,并且返回值写为person
    @Override
    public Person clone() throws CloneNotSupportedException {
        return (Person) super.clone();
    }
    ...
}

public class Main {

    public static void main(String[] args) throws Exception {
        Person person = new Person("fsx", 18);
        Object clone = person.clone();

        System.out.println(person);
        System.out.println(clone);
        System.out.println(person == clone); //false
    }
}

2.反序列化创建对象,在反序列化时,jvm会帮我们创建一个单独的对象,此时也不会调用任何的构造函数。此时需要让我们的类实现Serializable接口。

Java反射创建对象效率高还是通过new创建对象的效率高?

new创建的对象效率高,我们使用反射去创建对象时需要先去找类资源,使用类加载器创建,过程比较繁琐。

什么是反射?

反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语言的反射机制。

哪里用得到反射机制?

jdbc就是典型的反射

class.forName('com.mysql.jdbc.Driver.class');//加载MySQL的驱动类

很多框架都用到反射机制,注入属性,调用方法,如Spring。

获取Class对象有哪些方式?

  1. Class.forName(“类的路径”);
  2. 类名.class
  3. 对象名.getClass()
  4. 基本类型的包装类,可以调用包装类的Type属性来获得该包装类的Class对象。

java反射核心类

  1. Class:表示正在运行的Java应用程序中的类和接口
    • 所有获取对象的信息都需要Class类来实现。
  2. Field:提供有关类和接口的属性信息,以及对它的动态访问权限。
  3. Constructor:提供关于类的单个构造方法的信息以及它的访问权限
  4. Method:提供类或接口中某个方法的信息

反射的优缺点

优点:能够运行时动态获取类的实例,提高灵活性

缺点:使用反射性能较低,需要解析字节码,将内存中的对象进行解析。

如何使用java的反射

  1. 通过一个全限类名创建一个对象
    • Class.forName(“全限类名”); 例如:com.mysql.jdbc.Driver Driver类已经被加载到 jvm中,并且完成了类的初始化工作就行了
    • 类名.class; 获取Class<?> clz 对象
    • 对象.getClass();
  2. 获取构造器对象,通过构造器new出一个对象
    1. Clazz.getConstructor([String.class]);
    2. Con.newInstance([参数]);
  3. 通过class对象创建一个实例对象(就相当与new类名()无参构造器)
    1. Cls.newInstance();
  4. 通过class对象获得一个属性对象
    1. Field c=cls.getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。
    2. Field c=cls.getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的声明字段
  5. 通过class对象获得一个方法对象
    1. Cls.getMethod(“方法名”,class……parameaType);(只能获取公共的)
    2. Cls.getDeclareMethod(“方法名”);(获取任意修饰的方法,不能执行私有)
    3. M.setAccessible(true);(让私有的方法可以执行)
  6. 让方法执行
    1. Method.invoke(obj实例对象,obj可变参数);—–(是有返回值的)

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 15 天,点击查看活动详情