今天跟大家聊一个有趣的话题,在Java中两个Integer对象做比较时,会产生意想不到的结果。
在编程过程中,我们经常需要比较对象的相等性。有时候我们只关心对象的内容是否相等,而不关心它们是否引用同一个对象。例如,在集合类中,我们需要根据对象的内容进行查找、删除等操作,此时就需要判断对象的相等性。另外,对于基本数据类型(如 int、char 等),直接使用==运算符即可判断相等性,但对于对象则需要使用equals()方法来判断相等性。
全网最细面试题手册,支持艾宾浩斯记忆法。这是一份最全面、最详细、最高质量的 java 面试题,不建议你死记硬背,只要每天复习一遍,有个大概印象就行了。[2]
在 Java 的面试过程中,不可避免的一个面试题那就是 JVM ,而 JVM 的面试题中,有各种,比如在堆中会被问到的关于垃圾回收机制的相关问题,在栈中会被问到入栈以及出栈的过程,今天我们就来聊一下关于栈的相关问题,比如,栈帧和动态链接指的是什么?
关于这个问题应该是存在争议的。根据测试出来的结果和我们自己的经验,以及口口相传或是上学时老师讲的,我们认为是第一种。但第二种说法的呼声也很高,渐渐地我们也认为第2中才是对的。那么下面我们就来分析一下这个问题。
== : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象(基本数据类型==比较的是值,引用数据类型==比较的是内存地址)。
==操作符在Java中用于比较两个对象的引用是否相等。具体来说,当使用==操作符时,它会比较两个对象的引用是否指向内存中的同一位置。如果两个引用指向同一对象,则==返回true;否则返回false。
首先要明确的是:“对象传递(数组、类、接口)是引用传递,原始类型数据(整型、浮点型、字符型、布尔型)传递是值传递。”
这里会分享一些出现频率极其极其高的面试题,初定周更一篇,什么时候更完什么时候停止。
用来指示程序执行哪一条指令,这跟汇编语言的程序计数器的功能在逻辑上是一样的。JVM规范中规定,如果线程执行的是非native方法,则程序计数器中保存的是当前需要执行的指令地址,如果线程执行的是native方法,则程序计数器中的值undefined。每个线程都有自己独立的程序计数器。为什么呢?因为多线程下,一个CPU内核只会执行一条线程中的指令,因此为了使每个线程在线程切换之后能够恢复到切换之前的程序执行的位置,所以每个线程都有自己独立的程序计数器。
在讨论JVM内存区域分析之前,先来看一下Java程序具体执行的过程: Java 程序的执行过程:Java 源代码文件(.Java文件)-> Java Compiler(Java编译器)->Java 字
t=new Child();(创建了一个Child对象,并 把这个对象在堆内存中的地址赋给t)
原文链接:http://blog.csdn.net/humanking7/article/details/43583643
Java中没有指针的说法,Java中的引用就类似于C++的指针, Java的引用是栈区的一个变量, 如果引用的是基本数据类型,那它存储着就是栈区的一块内存,(因为普通基本数据类型由栈区管,long、int、short、byte、float、double、string、boolean),做形参时是传值调用; 如果引用的是new出来的实例(new String('a')也算,直接写'a'则存在栈区),则这个引用存储的是堆区一块内存的地址(这个时候就类似于C++的指针),做形参时是传引用调用,即C++中的传指针调用;
通常在面试中会被问到equals方法和==的区别,以及有没有重写过equals方法,以及重写equals方法的约定是什么? 下面简单的介绍一下我的理解: 首先,在比较基本类型中==和equals方法没有任何区别。 但是在比较引用类型,如对象中 equals 是通常是比较的是对象的实例是否相同。 ==通常是比较的是对象的实例的地址是否相同即对象实例的id。这是两个最重要的区别。 其次,重写equals方法的原则或者说约定是什么,以及什么时候应该覆盖equals呢 如果类具有自己特有的“逻辑相等”概念(不等同于对象等同的概念),而且超类还没有覆盖equals以实现期望的行为,这个时候我们要覆盖equals方法(通常属于值类的情况)。—来自于effective Java 中文版 但是在覆盖equals方法的时候要遵守的约定如下: equals方法实现了等价的关系 1.自反性。对于任何非null的引用值x,x.equals(x)都必须返回true 2.对称性。对于任何非null的引用值x和y,当且仅当x.equals(y)返回true的时候,y.equals(x)也必须返回true 3.传递性。对于任何非null的引用值x,y和z,如果x.equals(y)返回true,y.equals(z)返回true,则x.equals(z)也必须返回true。 4.一致性。对应任何非null的引用值x,y,只要equals比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)就会一致性的返回true或者一致性的返回false。—–来自于effective Java 中文版
从上图可以看出,java文件通过编译器变成了.class文件,接下来类加载器又将这些.class文件加载到JVM中。类加载器指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法内,然后再堆区创建一个java.lang.class对象,用来封装类在方法区内的数据结构。
Java 程序的执行过程:Java 源代码文件(.Java文件)-> Java Compiler(Java编译器)->Java 字节码文件(.class文件)->类加载器(Class Loader)->Runtime Data Area(运行时数据)-> Execution Engine(执行引擎)。 我们今天就来分析一下Java程序执行过程的 Runtime Data Area(运行时数据) 这一块。
不像 Java 和 .NET,Go 语言为程序员提供了控制数据结构的指针的能力;但是,你不能进行指针运算。通过给予程序员基本内存布局,Go 语言允许你控制特定集合的数据结构、分配的数量以及内存访问模式,这些对构建运行良好的系统是非常重要的:指针对于性能的影响是不言而喻的,而如果你想要做的是系统编程、操作系统或者网络应用,指针更是不可或缺的一部分。
Collection是集合类的上级接口,子接口有 Set、List、LinkedList、ArrayList、Vector、Stack、Set;
array array2 array3是变量,会创建在栈上,而它们对应的值会在堆上存放
"=="操作符在Java中用于比较两个对象的引用是否相等。换句话说,它检查两个引用是否指向内存中的同一位置。如果两个对象引用的是同一对象,那么"=="操作符就会返回true。
在Java中,编译器讲源代码转成字节码,那么字节码如何被执行的呢?这就涉及到了JVM的字节码执行引擎,执行引擎负责具体的代码调用及执行过程。就目前而言,所有的执行引擎的基本一致: 1. 输入:字节码文件 2. 处理:字节码解析 3. 输出:执行结果。
==和equals和hashcode是经常遇到但是很重要的内容,希望这篇文章能帮你理清概念。
如果reference类型的数据中存储的数值代表的是另外一块内存的起始地址,就称这块内存代表着一个引用。引用不等同于对象本身,根据虚拟机种类的不同,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置。
这是Java的经典问题。关于stackoverflow,已经提出了许多类似的问题,并且有很多不正确/不完整的答案。如果您考虑不多,问题很简单。但是,如果您对此进行更多考虑,可能会造成混乱。
在Java中,equals是在object类中的方法,在object中equals是用来看看两个参数是否引用的是同一个对象,而 == 可用于判断两个对象的地址是否相等,那么equals和 == 有什么区别?
CAS乐观锁(原子操作)
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来。 围城这个比喻过于形象!!! JVM内存区域 上经典图 【线程公有】:堆和方法区 【线程私有】
JVM在执行java程序时的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。
在写Java程序碰到一个问题,而正是这个问题引发了我对字符串的思考,Java示例代码如下:
对上面的问题,所谓的基本类型,因为没有对象话,所以 JVM 没有为基本类型创建实例化后的对象,因此 == 就可以直接用了,因为 2 个相同的基本类型的值的地址是一样的。
在 Native 代码中有时候会接收 Java 传入的引用类型参数,有时候也会通过 NewObject 方法来创建一个 Java 的引用类型变量。
如上面代码,简单说就是new User()的时候,会返回一个地址,并且将地址赋值给引用u,当这个引用被u持有的时候,java会认为这个对象时有用的,不会回收对象,如果你之后执行了好比说:
我们经常习惯性的写上if(str1==str2),这种写法在java中可能会带来问题
这句话声明了一个引用类型的变量,此时它并没有和任何对象关联。 而通过 new 来产生一个对象,并将这个对象和str1进行绑定:
new 运算符,new 创建对象实例(对象实例在堆内存中),对象引用指向对象实例(对象引用存放在栈内存中)。
在比较中==与equals对基本数据类型与引用数据类型的引用是不一样的,==对基本数据类型比较的是值,对引用数据类型比较的是地址,而equals默认比较的是地址,对基本数据类型会在比较完引用地址后再比较值是否相等,但是像String、Integer等包装的引用数据类型重写了equals来让他们的equals变为值的比较
这个时候可能会有疑问了,为什么add方法可以修改List数组,但是append和addNum却没有修改传进来的值
参数是按值而不是按引用传递的说明 Java 应用程序有且仅有的一种参数传递机制,即按值传递。
1 . Java 传递字符串数据到 JNI : 启动推流时 , Java 层会将 RTMP 推流地址传递给 JNI ;
JVM在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而一直存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。
使用 javac 将上述 Java 源码编译成 Class 字节码文件 Student.class ,
**优点:** 性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。
垃圾回收针对不同的分区又分为MinorGC和FullGC,不同分区的触发条件又有不同。总体来说GC的触发分为主动和被动两类:
程序计数器的生命周期是随着一条线程的启动而创建的,每一个线程独有一个程序计数器,多个线程之间互不影响。(可以理解为Java中的ThreadLocal,相关文章可参考:ThreadLocal及InheritableThreadLocal的原理剖析)
在面试的过程中往往会遇到javase的题目,这个又是容易被忽略,来看一下是哪些呢? 1)运行时异常,非运行时异常。 运行时异常可进行处理,也可不进行处理。非运行时异常必须进行处理(可以通过try-catch语句处理,也可通过关键字throws抛出异常)。非运行时异常继承自Exception但不继承自RuntimeException。 2)equals方法与“==”的区别 (1)对于字符串变量以及基本数据类型的包装类型来说:“==”比较两变量的引用是否相等,即变量在内存的首地址是否相等。“equals”比较实
equals的作用: 用于判断两个变量是否是对同一个对象的引用,即堆中的内容是否相同,返回值为布尔类型 String类型比较不同对象内容是否相同,应该用equals "=="操作符的作用 1、用于基本数据类型的比较 2、判断引用是否指向堆内存的同一块地址。 把String当作基本类型来使用时: 例:如果值不相同,对象就不相同,所以"==" 和equals结果一样 String s1 = "java"; String s2 = "java"; System.out.println(s1==s2);
public static void main(String[] args) {int a=1;change(a);System.out.println("交换a后的值:" a);}
Java 虚拟机栈(后文简称栈)是线程私有的,它的生命周期和线程相同,随着线程的创建而创建,随着线程的死亡而死亡。
优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。
领取专属 10元无门槛券
手把手带您无忧上云