java-对象的引用,赋值,基本类型与对象的关系

Java中,一切皆是对象!为何数据类型中还分为:基本类型和对象?不应该只有一个类型——对象吗?

1.首先,这问题问得很好!说明认真思考了。Java中一切皆是对象!这句话没错,因为八种基本类型都有对应的包装类(int的包装类是Integer),包装类自然就是对象了。 基本类型一直都是Java语言的一部分,这主要是基于程序性能的考量,基本类型定义定义的变量是存放在栈中,比如int i = 5;而Integer j = new Integer(10);j则只是一个对象的引用,存放在栈中,而实际的数值10则是放在堆里,堆的读写速度远不及栈了。再有就是基本类型定义的变量创建和销毁很快,而类定义的变量还需要JVM去销毁。

2.其实java不是100%的面向对象编程,比如基本数据类型如int,boolean等等都不是对象,也就是不能用new的方式获取,但是java对这些基本数据类型都有解决办法,就是对着一个封装类型,但是他们的封装类是对象。比如int对应着Integer,boolean对应着Boolean,他们都是为了解决基本数据类型面向对象用的。

对象与基本数据类型的区别
  • 基本数据类型在栈中进行分配,而对象类型在堆中进行分配。
  • 所有方法的参数都是在传递引用而非本身的值(基本类型例外)。
  • 对象之间的赋值只是传递引用,基本类型之间的赋值是创建新的拷贝。
  • 对于基本类型,“”和“!=”是在比较值。而对于对象来说,“”和“!=”是在比较两个引用是否相同。
  • 使用equals()方法有一点需要注意:equals()方法的默认行为是比较引用。如果是你自己写的类,你应该为它重写equals()来比较对象的内容。大多数Java类库都实现了比较对象内容的equals()方法。
  • 基本类型存储了实际的数值,而并非只想一个对象的引用,所以在为其赋值的时候,是直接将一个地方的内容复制到了另一个地方。例如,对基本数据类型使用a=b,那么b的内容就复制给a.若接着又修改了a,而b根本不会受这种修改的影响。

对一个对象赋值时,真正操作的是这个对象的引用。所以倘若“将一个对象赋值给另一个对象”,实际是将“引用”从一个地方复制到另一个地方。这意味着假若对对象使用c=d,那么c和d都指向原本只有d指向的那个对象。

Java对象及其引用
  • 对象的声明
  • 对象的创建
  • 对象的赋值

今天在学习链表翻转的时候搞不明白一点:对象赋值后只是对象的引用地址发生变化,也就是传递地址。

创建一个节点类
 public static class ListNode {
        int val;
        ListNode next = null;

         ListNode(int val) {
            this.val = val;
        }
     }
        ListNode node;//声明对象
        ListNode node1=new ListNode(1);//创建对象
        ListNode node2=new ListNode(2);//创建对象
         ListNode node3=new ListNode(3);
         node1.next=node2;
         node2.next=node3;
         node2=node3;


        System.out.println(node1.next.val);
        if(node2==node3)
            System.out.println("true");

关于上面的代码我认为的是这样的情况
由于node2=node3,所以就会变成下面的链表(我认为的这种情况是错误的)
java-对象的引用,赋值,基本类型与对象的关系_第1张图片
但是实际情况任然是下面这种链表
java-对象的引用,赋值,基本类型与对象的关系_第2张图片
原来实例化对象后就会在内存中开辟一个地址(node1、node2、node3都有地址),而node1、node2、node3代表的是一个地址引用,指向其开辟的地址。node2=node3只是将node2的地址应用指向了node3,但是原本node2开辟的地址依然存在。
当node2=node3后,对node2的值进行改变,相应的node3的也会改变。因为他们引用同一个地址。

测试

        ListNode node;//声明对象
        ListNode node1=new ListNode(1);//创建对象
        ListNode node2=new ListNode(2);//创建对象
         ListNode node3=new ListNode(3);
         node1.next=node2;
         node2.next=node3;
         node2=node3;


        System.out.println(node1.next.val);
        if(node2==node3)
            System.out.println("true");

输出
在这里插入图片描述
这证明node2=node3只是地址的引用发生了改变(node2和node3同时指向node3的地址),而原本node2开辟的地址依然没有改变。

链表的翻转

通过上述理解对象的引用可以完成链表的翻转

  public  ListNode reverse(ListNode listNode){
        ListNode head=new ListNode(-1);
        ListNode demo;
        while(listNode!=null){
            demo=listNode.next;
            listNode.next=head.next;
            head.next=listNode;
            listNode=demo;//这一步就是对象赋值,地址引用
        }
        return head.next;
    }

参考

https://blog.csdn.net/z69183787/article/details/21123605
https://blog.csdn.net/hdkjdhdj/article/details/53336116

你可能感兴趣的:(java基础入门)