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,所以就会变成下面的链表(我认为的这种情况是错误的)
但是实际情况任然是下面这种链表
原来实例化对象后就会在内存中开辟一个地址(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