我们将从以下常见问题进行讲解说明
- 除了 new创建对象以外,还有什么方式创建对象?
- Java反射创建对象效率高还是通过new创建对象的效率高?
- 什么是反射?
- 哪里用得到反射机制?
- 获取Class对象有哪些方式
- java反射核心类
- 反射的优缺点
- 如何使用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对象有哪些方式?
- Class.forName(“类的路径”);
- 类名.class
- 对象名.getClass()
- 基本类型的包装类,可以调用包装类的Type属性来获得该包装类的Class对象。
java反射核心类
- Class:表示正在运行的Java应用程序中的类和接口
- 所有获取对象的信息都需要Class类来实现。
- Field:提供有关类和接口的属性信息,以及对它的动态访问权限。
- Constructor:提供关于类的单个构造方法的信息以及它的访问权限
- Method:提供类或接口中某个方法的信息
反射的优缺点
优点:能够运行时动态获取类的实例,提高灵活性
缺点:使用反射性能较低,需要解析字节码,将内存中的对象进行解析。
如何使用java的反射
- 通过一个全限类名创建一个对象
- Class.forName(“全限类名”); 例如:com.mysql.jdbc.Driver Driver类已经被加载到 jvm中,并且完成了类的初始化工作就行了
- 类名.class; 获取Class<?> clz 对象
- 对象.getClass();
- 获取构造器对象,通过构造器new出一个对象
- Clazz.getConstructor([String.class]);
- Con.newInstance([参数]);
- 通过class对象创建一个实例对象(就相当与new类名()无参构造器)
- Cls.newInstance();
- 通过class对象获得一个属性对象
- Field c=cls.getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。
- Field c=cls.getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的声明字段
- 通过class对象获得一个方法对象
- Cls.getMethod(“方法名”,class……parameaType);(只能获取公共的)
- Cls.getDeclareMethod(“方法名”);(获取任意修饰的方法,不能执行私有)
- M.setAccessible(true);(让私有的方法可以执行)
- 让方法执行
- Method.invoke(obj实例对象,obj可变参数);—–(是有返回值的)
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 15 天,点击查看活动详情