欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【面试】反射相关-这一篇全了解

程序员文章站 2022-03-09 21:36:15
...

什么是Java的反射机制?

答:反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有属性和方法。

Java中的反射有什么作用?

解:

在运行时判断任意一个对象所属的类。

在运行时判断任意一个类所具有的成员变量和方法。

在运行时任意调用一个对象的方法

在运行时构造任意一个类的对象

反射有哪些优缺点?

解:

优点

反射提高了程序的灵活性和扩展性。

缺点

代码可读性低及可维护性

反射代码执行的性能低

破坏了封装性。

在业务代码中应该尽量避免使用反射。但是,作为一个合格的Java开发,也要能读懂中间件、框架中的反射代码。在有些场景下,要知道可以使用反射解决部分问题。

反射常见的用法有哪些。或者你在框架中哪些地方见过反射的使用?

解:

动态代理

JDBC的class.forName

BeanUtils中属性值得拷贝

RPC框架

ORM框架

Spring的IOC/DI

什么是Java中的Class类,他和反射有什么关系?

解:

Java的Class类是java反射机制的基础,通过Class类我们可以获得关于一个类的相关信息

Java.lang.Class是一个比较特殊的类,它用于封装被装入到JVM中的类(包括类和接口)的信息。当一个类或接口被装入的JVM时便会产生一个与之关联的java.lang.Class对象,可以通过这个Class对象对被装入类的详细信息进行访问。

虚拟机为每种类型管理一个独一无二的Class对象。也就是说,每个类(型)都有一个Class对象。运行程序时,Java虚拟机(JVM)首先检查是否所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。

获取“某一个类”所对应的“Class对象”有哪几种方法?

解:

1.根据对象的引用.getClass()方法获取:MyObject object=new MyObject();  Class c=object.getClass();

2.根据类名.class获取:Class c=MyObject.class;

3.根据Class中的静态方法Class.forName(); Class c=Class.forName("MyObject");

Java中创建对象的方法有几种?

解:

一、使用new关键字

这是我们最常见的也是最简单的创建对象的方式,通过这种方式我们还可以调用任意的构造函数(无参的和有参的)。

例如:

User user = new User();

二、使用反射机制

运用反射手段,调用Java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。

1 使用Class类的newInstance方法

可以使用Class类的newInstance方法创建对象。这个newInstance方法调用无参的构造函数创建对象。

//创建方法1

User user = (User)Class.forName("根路径.User").newInstance();

//创建方法2(用这个最好)

User user = User.class.newInstance();

2 使用Constructor类的newInstance方法

和Class类的newInstance方法很像, java.lang.reflect.Constructor类里也有一个newInstance方法可以创建对象。我们可以通过这个newInstance方法调用有参数的和私有的构造函数。

Constructor<User> constructor = User.class.getConstructor();

User user = constructor.newInstance();

这两种newInstance方法就是大家所说的反射。事实上Class的newInstance方法内部调用Constructor的newInstance方法。

三、使用clone方法

无论何时我们调用一个对象的clone方法,jvm就会创建一个新的对象,将前面对象的内容全部拷贝进去。用clone方法创建对象并不会调用任何构造函数。

要使用clone方法,我们需要先实现Cloneable接口并实现其定义的clone方法。

public class CloneTest implements Cloneable{
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public CloneTest(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public static void main(String[] args) {
        try {
            CloneTest cloneTest = new CloneTest("wangql",18);
            CloneTest copyClone = (CloneTest) cloneTest.clone();
            System.out.println("newclone:"+cloneTest.getName());
            System.out.println("copyClone:"+copyClone.getName());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

四、使用反序列化

当我们序列化和反序列化一个对象,jvm会给我们创建一个单独的对象。在反序列化时,jvm创建对象并不会调用任何构造函数。

为了反序列化一个对象,我们需要让我们的类实现Serializable接口。

学习文章:Java对象的序列化与反序列化

对象的序列化和反序列化涉及的东西比较多,等补充后再总结。

实现功能:在泛型为Integer的ArrayList中存放一个String类型的对象。

    public void test() throws Exception {
        ArrayList<Integer> list = new ArrayList<Integer>();
        Method method = list.getClass().getMethod("add", Object.class);
        method.invoke(list, "Java反射机制实例");
        System.out.println(list.get(0));
    }

 

相关标签: 反射