首页 > 编程语言 >[Java基础]

[Java基础]

时间:2024-07-09 19:30:57浏览次数:11  
标签:Java name 对象 age 基础 address 拷贝 public

数据类型

Java的数据类型包括基本数据类型和引用数据类型:

基本数据类型:

  • 整形:byte, short, int, long

  • 浮点型:float, double

  • 字符型:char

  • 布尔型:boolean

引用数据类型:class, interface, array。

引用拷贝,浅拷贝,深拷贝

引用拷贝
在Java中,对象的引用拷贝是指将一个对象的引用赋值给另一个变量。通过引用拷贝,两个变量将指向同一个对象,它们共享同一块内存空间。当修改其中一个变量指向的对象时,另一个变量也会受到影响。

下面是一个简单的示例代码,演示了对象引用拷贝的概念:

public class Test {
    public static void main(String[] args) {

        // 创建一个Person对象
        Person person1 = new Person("Alice", 25);

        // 将person1的引用拷贝给person2
        Person person2 = person1;

        System.out.println("person1: " + person1);
        System.out.println("person2: " + person2);

        // 修改person1的属性
        person1.setName("Bob");
        person1.setAge(30);

        System.out.println("person1: " + person1);
        System.out.println("person2: " + person2);
		
        // True
        System.out.println(person1 == person2);

    }

}


class Person {
    private String name;
    private int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
    
    @Override
    public String toString() {
        return "Person[name=" + name + ", age=" + age + "]";
    }
}

在上述代码中,创建了一个Person对象person1,然后将其引用拷贝给person2。修改person1的属性后,打印person1和person2的值,可以发现它们指向同一个对象,因此修改person1的属性后,person2的属性也会相应改变。

输出结果如下:

person1: Person[name=Alice, age=25]
person2: Person[name=Alice, age=25]
person1: Person[name=Bob, age=30]
person2: Person[name=Bob, age=30]
true
可以看到,通过引用拷贝,person1和person2指向同一个Person对象,修改其中一个对象的属性会影响另一个对象。

浅拷贝
在Java中,浅拷贝(Shallow Copy)是指创建一个新对象,并将原始对象中的所有字段的值复制到新对象中。浅拷贝只是简单地复制对象的字段值,如果对象中包含引用类型的字段,则新对象和原始对象会共享这些引用类型的字段。

浅拷贝是通过复制对象的引用来实现的,也就是说,新对象和原始对象指向了同一个内存地址。因此,如果修改了新对象的引用类型字段的值,原始对象的引用类型字段的值也会被修改,因为它们指向同一个对象。

要实现浅拷贝,可以使用以下几种方式:

使用Object类的clone()方法:Object类中的clone()方法可以复制一个对象,但它只复制对象的字段值,不复制引用类型字段指向的对象。因此,如果对象中包含引用类型字段,那么新对象和原始对象会共享这些引用类型的字段。

使用拷贝构造函数:通过定义一个构造函数,参数为原始对象,将原始对象中的字段值复制到新对象中。

需要注意的是,浅拷贝只是复制对象的字段值,而不复制对象内部的引用类型字段的值。因此,如果需要实现深拷贝,就需要对引用类型字段进行递归拷贝,确保新对象和原始对象的引用类型字段指向不同的对象。

public class Address {
    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Address(String address) {
        this.address = address;
    }
}

class Person implements Cloneable {
    private String name;
    private int age;

    private Address address;

    public Person(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public Address getAddress() {
        return address;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return this.name + "-" + this.age + "-" + this.address.getAddress();
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {

        Address address1 = new Address("山东");
        Person person1 = new Person("Alice", 25, address1);
        Person person2 = (Person) person1.clone();

        System.out.println(person1);
        System.out.println(person2);

        person1.setAge(30);
        address1.setAddress("上海");

        System.out.println(person1);
        System.out.println(person2);
        
        //Alice-25-山东
        //Alice-25-山东
        //Alice-30-上海
        //Alice-25-上海

    }

}

深拷贝
在 Java 中,深拷贝(Deep Copy)是指创建一个新对象,将原始对象中的所有字段的值都复制到新对象中。深拷贝会递归复制对象的所有层级,包括对象的引用类型字段,确保新对象和原始对象完全独立相对地,浅拷贝(Shallow Copy)只是简单地复制对象的字段值,如果对象中包含引用类型的字段,那么新对象和原始对象会共享这些引用类型的字段。

为了实现深拷贝,可以使用以下几种方式:

实现 Cloneable接口和覆写 clone() 方法:通过实现 Cloneable 接口来指明对象可以进行拷贝操作,并覆写 clone() 方法来实现深拷贝的逻辑。

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        
        Person person1 = new Person("Alice", 25, new Address("山东"));
        Person person2 = (Person) person1.clone();

        System.out.println(person1);
        System.out.println(person2);

        person2.setName("david");
        person2.setAge(30);
        person2.getAddress().setAddress("上海");

        System.out.println(person1);
        System.out.println(person2);
        
        
        //Alice-25-山东
        //Alice-25-山东
        //Alice-25-山东
        //david-30-上海

    }

}

public class Address implements Cloneable{
    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Address(String address) {
        this.address = address;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Address clone = (Address) super.clone();
        clone.setAddress(this.address);
        return clone;
    }
}




class Person implements Cloneable {
    private String name;
    private int age;

    private Address address;

    public Person(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public Person() {

    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public Address getAddress() {
        return address;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return this.name + "-" + this.age + "-" + this.address.getAddress();
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person res = (Person) super.clone();
        res.address = (Address) this.address.clone();
        return res;
    }
}


使用序列化和反序列化:通过将对象序列化为字流,再将字节流反序列化为新对象来实现深拷贝。

public class MyClass implements Serializable {
    private int value;
    private MyObject obj;

    // 构造函数和其他方法
    
    public MyClass deepCopy() throws IOException, ClassNotFoundException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(this); // 序列化当前对象
    
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return (MyClass) ois.readObject(); // 反序列化生成新对象
    }

}

需要注意的是,为了现深拷贝,不仅仅需要拷贝对象本身,还需要拷贝对象内部的引用类型字段。因此,如果引用类型字段也需要支持深拷贝,那么该引用类型也需要实现 Cloneable 接口或者序列化接口,并在拷贝方法中进行递归拷。

浅拷贝和深拷贝的区别
在Java中,浅拷贝(Shallow Copy)和深拷贝(Deep Copy)是两种不同的对象拷贝方式,它们的主要区别如下:

  • 复制的内容不同:
    • 浅拷贝只复制对象的字段值,不复制引用类型字段指向的对象。
    • 深拷贝会递归复制对象的所有层级,包括对象的引用类型字段。
  • 对象的独立性不同:
    • 浅拷贝复制后的对象与原始对象共享相同的引用类型字段,即它们指向相同的对象。
    • 深拷贝复制后的对象与原始对象完全独立,它们的引用类型字段指向不同的对象。
  • 对象修改的影响不同:
    • 浅拷贝中,如果修改新对象的引用类型字段的值,原始对象的相应字段也会被修改,因为它们指向同一个对象。
    • 深拷贝中,修改新对象的引用类型字段的值不会影响原始对象的相应字段,因为它们指向不同的对象。
  • 实现方式不同:
    • 浅拷贝可以通过Object类的clone()方法、拷贝构造函数等方式实现。
    • 深拷贝需要对对象的引用类型字段进行递归拷贝,可以通过实现Cloneable接口和覆盖clone()方法、使用序列化和反序列化等方式实现。

总结来说,浅拷贝只复制对象的字段值,不复制引用类型字段指向的对象,而深拷贝会递归复制所有层级的对象,确保新对象和原始对象完全独立。因此,深拷贝相比浅拷贝更加安全,但也需要更多的资源和性能开销。选择使用哪种拷贝方式,需要根据具体的场景和需求来决定。

标签:Java,name,对象,age,基础,address,拷贝,public
From: https://www.cnblogs.com/DCFV/p/18292608

相关文章

  • [Java基础]反射
    反射获取任意对象的数据对对象一无所知的情况下publicclassStudent{privateStringname;privateIntegerage;publicStudent(Stringname,Integerage){this.name=name;this.age=age;}publicStringgetName(){......
  • [Java并发]Lock
    锁锁的分类公平锁/非公平锁可重入锁独享锁/共享锁互斥锁/读写锁乐观锁/悲观锁分段锁偏向锁/轻量级锁/重量级锁自旋锁公平锁/非公平锁公平锁是指多个线程按照申请锁的顺序来获取锁。非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先......
  • [Java并发]IO多路复用
    IOIO多路复用BIONIOselectpollepoll水平触发和边沿触发水平触发只关心文件描述符中是否还有没完成处理的数据,如果有,不管怎样epoll_wait,总是会被返回。简单说——水平触发代表了一种“状态”。边沿触发只关心文件描述符是否有新的事件产生,如果有,则返回;如果返回过一次,......
  • [Java面试]经典手撕
    多线程循环打印ABC方法一:packageorg.example;importjava.util.TreeMap;importjava.util.concurrent.locks.Condition;importjava.util.concurrent.locks.ReentrantLock;publicclassPrintABC{ReentrantLocklock=newReentrantLock();Conditiona=lo......
  • [Java基础]HashMap
    HashMapHashMap的数据结构HashMap是:数组+链表/红黑树(JDK1.8增加了红黑树部分)数据底层具体存储的是什么?Node<k,v>这样的存储方式有什么优点呢?数据结构//默认初始容量(数组默认大小):16,2的整数次方staticfinalintDEFAULT_INITIAL_CAPACITY=1<<4;//最大......
  • java day1
    简单了解了java,他最大的特点就是,稳定,安全,可以解决高并发的访问,最大的优势.java分es,ee,me.java的强势之处在于javaee,我是从javase开始学的.2.安装JDk,我装的是JDK17,据说当前市场大多数用的都是JDK8,17在未来可能会占据更大市场.17也是长期支持版.安装步骤(1)访问甲骨文......
  • [Java并发]Synchronized
    publicclassAtomicTest01{publicstaticinti=0;publicstaticvoidmain(String[]args){Runnabletask=newRunnable(){@Overridepublicvoidrun(){synchronized(this){tr......
  • Gradle基础:从入门到掌握
    人不走空                                          ......
  • Java爬虫翻页
    编写一个Java爬虫以进行翻页通常涉及到使用HTTP客户端(如ApacheHttpClient或OkHttp)来发送请求,解析HTML页面(如使用Jsoup库),以及处理分页逻辑(如通过URL参数或页面内的链接进行翻页)。1.使用Jsoup和ApacheHttpClient的Java爬虫示例以下是一个使用Jsoup和ApacheHttpClient的Java爬......
  • 对零基础想转行网络安全同学的一点建议
    最近有同学在后台留言,0基础怎么学网络安全?0基础可以转行做网络安全吗?以前也碰到过类似的问题,想了想,今天简单写一下。我的回答是先了解,再入行。具体怎么做呢?首先,你要确定学习方向。网络安全是一个很大的概念,包含的东西也很多,比如web安全,系统安全,二进制安全,无线安全、数......