多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
### JAVA对象实例化的方法 ##### New对象实例 ``` // 直接new对象实例 Productor productor = new Productor(); ``` _注意:任何类都有构造方法,但是new指令只能创建非抽象类的对象;构造方法不能是静态的,因为静态方法不能使用this,而构造方法中可以使用_ ##### 反射机制 Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。 反射机制创建对象分为两种,一种是Class类的newInstance\(\),另一种是java.lang.reflect.Constructor类的newInstance\(\)。 两者区别在于: * Class.newInstance\(\) 只能够调用无参的构造函数,即默认的构造函数; * Constructor.newInstance\(\) 可以根据传入的参数,调用任意构造构造函数。 事实上Class的newInstance方法内部调用Constructor的newInstance方法。 反射机制创建对象,使用的是类加载机制,newInstance\(\)的特点是在调用时才创建对象,通过类加载机制Class.forName\("xxx"\).newInstance\(\)创建对象,xxx可以从配置文件当中获取实际的值,这样达到了解耦的目的,也是Spring依赖注入的原理 ``` // 1.通过反射调用Java.lang.Class Productor productor = (Productor) Class.forName("com.quancheng.Productor").newInstance(); Productor productor = Productor.class.newInstance(); // 2.java.lang.reflect.Constructor类的newInstance()实例方法 Constructor<Productor> constructor = Productor.class.getConstructor(); Productor productor = constructor.newInstance(); ``` ##### clone\(\)方法 clone方法分为浅拷贝和深拷贝 * 浅拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。 * 深拷贝:不仅要复制对象的所有非引用成员变量值,还要为引用类型的成员变量创建新的实例,并且初始化为形式参数实例值。 浅拷贝的效果就是,对引用对象的操作,会影响到所有引用了该对象的对象 ``` public class Object { // clone方法定义 protected native Object clone() throws CloneNotSupportedException; } ``` _注意:_ 1. _Cloneable只是一个标志,想要使用super.clone\(\),则需要实现Cloneable接口,否则就会抛出CloneNotSupportedException异常;_ 2. _clone\(\)实现的是浅复制,在重载clone方法的时候,需要转为深复制。即属性存在对象引用的时候,需要对引用属性再进行clone\(\)复制,直到没有对象引用;_ ``` public class Appliction { public static void main(String[] args) throws CloneNotSupportedException { User user = new User(); user.setName("Tom"); user.setAge(20); user.setWeight(120); System.err.println(user); User u = (User) user.clone(); System.err.println(u); } } class User implements Cloneable { private String name; private int age; private Integer weight; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } ...... } ``` ##### 反序列化 序列化对象就是对象此刻在内存中的状态转成的字节码。通过实现Serializable接口进行序列化。同Cloneable一样,Serializable也是一个空接口,作为一个标志使用。通过ObjectStream的writeObject\(\)方法和readObject\(\)方法来序列化和反序列化 还有一个Externalizable接口同样可以实现序列化,Externalizable继承了Serializable,同时增加了writeExternal\(\)和readExternal\(\)两个方法,可以指定序列化哪些属性,对于需要隐藏的属性,在前面加上transient就可以。 _注意:序列化和反序列化是深复制,static、transient 后的变量无法序列化_ ##### Unsafe 使用Unsafe"黑科技"实例化对象 ``` public class Appliction { private static Unsafe U; public static void main(String[] args) throws InstantiationException { User user = (User) U.allocateInstance(User.class); user.setName("Tom"); System.err.println(user.getName()); } static { try { Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafe.setAccessible(true); U = (Unsafe) theUnsafe.get("null"); } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); } } } class User implements Cloneable { private String name; private int age; private Integer weight; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } ...... } ``` _注意:使用Unsafe方法实例化对象不会调用对象的构造方法_