博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java 创建对象以及类加载 详解
阅读量:2393 次
发布时间:2019-05-10

本文共 3710 字,大约阅读时间需要 12 分钟。

java 创建对象有多种方式 :
方式1> new
方式2> 使用 Object 的 clone 方法
    <1> 实现 clone类 首先实现 Cloneble接口,Cloneable接口 实质上是一个标识接口 类似于 Serializable 接口,没有任何方法
    <2> 重写 Object 中的 clone方法
    <3> 在 clone方法中调用 super.clone(),无论 clone类 的继承结构是什么,super.clone() 都会直接或间接调用 Object类 中的 clone方法
public class Obj implements Cloneable {
    private int a = 0;
    public Obj() {
        System.out.println("construct Obj");
    }
    public int getA() {
        return a;
    }
    public void setA(int a) {
        this.a = a;
    }
    public void changeA() {
        this.a = 1;
    }
    // 将 protected 作用域改成 public
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public static void main(String[] args) {
        try {
            Obj a = new Obj();
            Obj b = (Obj) a.clone();
            b.changeA();
            System.out.println(a.getA());
            System.out.println(b.getA());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 打印
    // construct Obj    # 只打一个一次,说明没有进行两次 new 操作
    // 0    # 两次打印的结果不同,说明 a b 指向的不是同一个对象
    // 1
}
方式3> 利用反射
public class Person {
    private String name = "Jack";
    public Person() {
        System.out.println("construct Person");
    }
    @Override
    public String toString() {
        return name;
    }
    public static void main(String[] args) {
        Class clazz;
        try {
            clazz = Class.forName("com.chenshun.test.object.Person");
            Person p = (Person) clazz.newInstance();
            System.out.println(p);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
方式4> 通过反序列化来创建对象
public class People implements Serializable {
    private static final long serialVersionUID = 8561166444504657722L;
    private String name;
    public People() {
        this.name = "6点A君";
        System.out.println("construct people");
    }
    @Override
    public String toString() {
        return this.name;
    }
    public static void main(String[] args) {
        People p = new People();
        System.out.println(p);
        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;
        try {
            FileOutputStream fos = new FileOutputStream("test.out");
            oos = new ObjectOutputStream(fos);
            oos.writeObject(p);
            oos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        People p1;
        try {
            FileInputStream fis = new FileInputStream("test.out");
            ois = new ObjectInputStream(fis);
            p1 = (People) ois.readObject();
            System.out.println(p1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Java 中 Class.forName() 和 ClassLoader 都可用来对类进行加载
1> Class.forName() 用于将类的 .class文件 加载到 JVM,还可以对类进行解释,执行类中的 static块。另外,Class.forName(name, initialize, loader) 带参函数也可控制是否加载 static块。并且只有调用 newInstance()方法采用调用构造函数,创建类的对象
2> ClassLoader 只干一件事情,就是将 .class文件加载到 JVM 中,不会执行 static 中的内容,只有在 newInstance 才会去执行 static块
public class Point {
    static {
        System.out.println("静态代码块执行:loading point");
    }
}
`
private static void testClassloader(String wholeNamePoint) {
    Class<?> point;
    ClassLoader loader = ClassLoader.getSystemClassLoader();
    try {
        point = loader.loadClass(wholeNamePoint);
        
// demo = ClassloaderAndForNameTest.class.getClassLoader().loadClass(wholeNamePoint); // 这个也是可以的
        System.out.println("point   " + point.getName());
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

private static void testForName(String wholeNamePoint) {
    try {
        Class point = Class.forName(wholeNamePoint);
        System.out.println("point   " + point.getName());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) {
    String wholeNamePoint = "com.chenshun.test.object.Point";
    System.out.println("下面是测试Classloader的效果");
    testClassloader(wholeNamePoint);
    System.out.println("----------------------------------");
    System.out.println("下面是测试Class.forName的效果");
    testForName(wholeNamePoint);
}
# 打印
下面是测试Classloader的效果
point   com.chenshun.test.object.Point
----------------------------------
下面是测试Class.forName的效果
静态代码块执行:loading point
point   com.chenshun.test.object.Point
这个案例需要注意的是如果 main 方法在 Point 中将会先打印 "静态代码块执行:loading point" 然后再执行其它操作,这是由于运行 main 方法前会先运行静态代码块 有 Java 成员运行顺序决定

转载地址:http://qagab.baihongyu.com/

你可能感兴趣的文章
[转]Ubuntu 10.04 LTS 安装 sun-java6-jdk
查看>>
[转]mmap详解
查看>>
[转]HDFS和KFS 比较
查看>>
Oracle 12CR2 Oracle Restart - ASM Startup fails with PRCR-1079
查看>>
poj 2140 Herd Sums
查看>>
poj 2524 Ubiquitous Religions
查看>>
poj 1611 The Suspects
查看>>
poj 3331 The Idiot of the Year Contest!
查看>>
poj 3233 Matrix Power Series
查看>>
poj 3070 Fibonacci
查看>>
poj 1656 Counting Black
查看>>
BestCoder Round #28
查看>>
poj1845 Sumdiv
查看>>
poj3299 Humidex
查看>>
poj2159 Ancient Cipher
查看>>
poj1083 Moving Tables
查看>>
poj2255 Tree Recovery
查看>>
poj3904 Sky Code
查看>>
zoj 1745 Are We There Yet?
查看>>
UVA100 The 3n + 1 problem
查看>>