一、==符的使 
首先看一段比较有意思的代码 
Integer a = 1000,b=1000; 
Integer c = 100,d=100; public void mRun(final String name){ new Runnable() { public void run() { System.out.println(name); } }; } 
System.out.println(a==b); 
System.out.println(c==d); 
如果这道题你能得出正确答案,并能了解其中的原理的话。说明你基础还可以。如果你的答案 是 true 和true的话,你的基础就有所欠缺了。 
首先公布下答案, 运行代码,我们会得到 false true。我们知道==比较的是两个对象的引用,这里的abcd都是新建出来的对象,按理说都应该输入false才对。这就是这道题的有趣之处,无论是面试题还是论坛讨论区,这道题的出场率都很高。原理其实很简单,我们去看下Integer.java这个类就了然了。 
如果你想学习java可以来这个群,首先是一二六,中间是五三四,最后是五一九,里面有大量的谢谢资料可以下载。 
public static Integer valueOf(int i) { return i >= 128 || i < -128 new Integer(i) : SMALL_VALUES[i + 128]; } /A cache of instances used by {@link Integer#valueOf(int)} and auto-boxing */ private static final Integer[] SMALL_VALUES = new Integer[256]; static { for (int i = -128; i < 128; i++) { SMALL_VALUES[i + 128] = new Integer(i); } } 
当我们声明一个Integer c = 100;的时候。此时会进行自动装箱操作,简单点说,也就是把基本数据类型转换成Integer对象,而转换成Integer对象正是调用的valueOf方法,可以看到,Integer中把-128-127 缓存了下来。官方解释是小的数字使用的频率比较高,所以为了优化性能,把这之间的数缓存了下来。这就是为什么这道题的答案回事false和ture了。当声明的Integer对象的值在-128-127之间的时候,引用的是同一个对象,所以结果是true。

二、String 
接着看代码 
String s1 = “abc”; 
String s2 = “abc”; 
String s3 = new String(“abc”); 
System.out.println(s1 == s2); 
System.out.println(s1 == s3); 
大家又来猜一猜这道题的答案是什么? 
按照==的语法来看, 首先s1、s2、s3是三个不同的对象,常理来说,输出都会是false。然而程序的运行结果确实true、false。第二个输出false可以理解,第一个输出true就又让人费解了。我们知道一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,而堆内存中则存放new 出来的对象和数组。然而除此之外还有一块区域叫做常量池。 
像我们通常想String s1 = “abc”; 这样申明的字符串对象,其值就是存储在常量池中。当我们创建String s1 = “abc”这样一个对象之后,”abc”就存储到了常量池(也可叫做字符串池)中,当我们创建引用String s2 = “abc” 的时候,Java底层会优先在常量池中查找是否存在”abc”,如果存在则让s2指向这个值,不会重新创建,如果常量池中没有则创建并添加的池中。这就是为什么答案是true 和false的原因。 
三、final关键字 
还是来看一段代码 
public void mRun(final String name){ new Runnable() { public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(name); } }.start(); } 
这种代码相信大家写过很多,当内部类访问局部变量的时候,需要在局部变量前加final修饰符,不然编译器就会报错。通常我们也是这么干的。好的,第二个问题来了,为什么要加final修饰符?相信大多数小伙伴都没有思考过这个问题,但凡使用的时候,直接加上就得了,从来没去深究过其中的原理。这对于一个优秀的程序员来说是不可取,我们不仅要知其然还要知其所以然。 
现在我们来分析一下,为什么要加final关键字。首先内部类的生命周期是成员级别的,而局部变量的生命周期实在方法体之类。也就是说会出现这样一种情况,当mRun方法执行,new 的线程运行,新线程里面会睡一秒。主线程会继续执行,mRun执行完毕,name属性生命周期结束。 
1秒之后,Syetem.out.printh(name)执行。然而此时name已经寿终正寝,不在内存中了。Java就是为了杜绝这种错误,严格要求内部类中方位局部变量,必须使用final关键字修饰。局部变量被final修饰之后,此时会在内存中保有一份局部变得的复制品,当内部类访问的时候其实访问的是这个复制品。这就好像是把局部变量的生命周期变长了。说到底还是Java工程师提前把这个坑给我们填了,不然不知道又会有多少小伙伴会为了内部类局部变量而发愁了。 
四、Integer与int那些事 
看下面代码 
Integer a = new Integer(1000); 
int b = 1000; 
Integer c = new Integer(10); 
Integer d = new Integer(10); 
System.out.println(a == b); 
System.out.println(c == d); 
这道题是继第一题的后续,如果这道题你能很快速的得出答案,那么恭喜你,==比较符你就算掌握的比较透彻了。 
——————————————————分割线—————————————————————————————– 
正确答案: true 、false 
看到这个答案很多小伙伴又会不解,先来说下第二个,按第一题来说Integer不是把-128-127缓存起来了吗?这不是应该是true嘛,但是你仔细看,这里的Integer是我们自己new出来的,并不是用的缓存,所以结果是false。 
现在来看第一个为啥又是true了呢? 首先这里的值为1000,肯定和我们所知的Integer缓存没有关系。既然和缓存没有关系,a是新new出来的对象,按理说输入应该是false才对。但是注意b这里是int类型。当int和Integer进行==比较的时候,Java会把Integer进行自动拆箱,也就是把Integer转成int类型,所以这里进行比较的是int类型的值,所以结果即为true。

四道java语言练习基础题:的更多相关文章

  1. 2.4JAVA基础复习——JAVA语言的基础组成数组

    JAVA语言的基础组成有: 1.关键字:被赋予特殊含义的单词. 2.标识符:用来标识的符号. 3.注释:用来注释说明程序的文字. 4.常量和变量:内存存储区域的表示. 5.运算符:程序中用来运算的符号 ...

  2. 2.3JAVA基础复习——JAVA语言的基础组成函数

    JAVA语言的基础组成有: 1.关键字:被赋予特殊含义的单词. 2.标识符:用来标识的符号. 3.注释:用来注释说明程序的文字. 4.常量和变量:内存存储区域的表示. 5.运算符:程序中用来运算的符号 ...

  3. 2.2JAVA基础复习——JAVA语言的基础组成运算符和语句

    JAVA语言的基础组成有: 1.关键字:被赋予特殊含义的单词. 2.标识符:用来标识的符号. 3.注释:用来注释说明程序的文字. 4.常量和变量:内存存储区域的表示. 5.运算符:程序中用来运算的符号 ...

  4. 2.1JAVA基础复习——JAVA语言的基础组成注释和常量变量

    JAVA语言的基础组成有: 1.关键字:被赋予特殊含义的单词. 2.标识符:用来标识的符号. 3.注释:用来注释说明程序的文字. 4.常量和变量:内存存储区域的表示. 5.运算符:程序中用来运算的符号 ...

  5. 2.0JAVA基础复习——JAVA语言的基础组成关键字和标识符

    JAVA语言的基础组成有: 1.关键字:被赋予特殊含义的单词. 2.标识符:用来标识的符号. 3.注释:用来注释说明程序的文字. 4.常量和变量:内存存储区域的表示. 5.运算符:程序中用来运算的符号 ...

  6. java面试| 精选基础题(3)

    每天进步一点点,距离大腿又近一步! 阅读本文大概需要6分钟 系列文章 java面试| 精选基础题(1) java面试|精选基础题(2) 1.float f=3.4;是否正确? 答:不正确,编译无法通过 ...

  7. java面试| 精选基础题(2)

    关注微信公众号"java从心",置顶公众号 每天进步一点点,距离大腿又近一步! 阅读本文大概需要6分钟 继续挖掘一些有趣的基础面试题,有错望指出来哈,请赐教~ 1.包装类的装箱与拆 ...

  8. 0031 Java学习笔记-梁勇著《Java语言程序设计-基础篇 第十版》英语单词

    第01章 计算机.程序和Java概述 CPU(Central Processing Unit) * 中央处理器 Control Unit * 控制单元 arithmetic/logic unit /ə ...

  9. Java语言程序设计(基础篇)第一章

    第一章 计算机.程序和Java概述 1.1 引言 什么是程序设计呢? 程序设计就是创建(或者开发)软件,软件也称为程序. 1.2 什么是计算机 计算机是存储和处理数据的电子设备,计算机包括硬件(har ...

随机推荐

  1. shell中利用ftp 上传文件夹功能

    我们知道ftp 只能用来上传或者下载文件,一次单个或者多个,怎么实现将文件夹的上传和下载呢? 可以利用先在remote ip上建立一个相同的文件夹目录,然后将文件放到各自的目录中去 1.循环遍历出要上 ...

  2. JS---基础用法2

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  3. foreach中collection的三种用法

    转载:http://blog.sina.com.cn/s/blog_b0d90e8c0102v1q1.html 传参参考:http://www.cnblogs.com/ruiati/p/6410339 ...

  4. java.lang.NoClassDefFoundError: javassist/util/proxy/MethodFilter

    转自:https://blog.csdn.net/rchm8519/article/details/23788053 1. ERROR - Context initialization failedo ...

  5. error: field has incomplete type

    在头文件使用某一自定义的类的指针或引用时,只需要前置声明该类即可,然而如果该类中有静态成员时,必须包含该类的头文件,而不是使用前置声明.

  6. 阿里云服务器CentOS7中Tomcat8.x启动慢问题解决记录

    公司服务器刚换CentOS7,在内部的刀片机上一直跑的很溜,迁移到阿里云上后Tomcat启动竟然要6.7分钟!这还了得. 且日志上无任何错误,在日志中查看到如下信息: Log4j:[2015-10-2 ...

  7. opengl1

    OpenGL Programming Guide Programming Guide > Chapter 1 Chapter 1 Introduction to OpenGL Chapter O ...

  8. (I/O完成端口中的)995错误

    在windows下,可能会出现995的错误,msdn对该错误的解释为: The I/O operation has been aborted because of either a thread ex ...

  9. Eclipse与IntelliJ IDEA区别

    1.没有workspace,新增modules(Workspace-Project,Project-Module) 2.没有perspectives,自动根据上下文调用相关工具 3.没有保存按钮,自动 ...

  10. Hadoop 2.7.3 HA 搭建及遇到的一些问题

    看了Hadoop的一个7天视频教程,里面给出了搭建的详细步骤,教程中是按2.4.1版本搭建的,我用的是2.7.3版本,好像没什么差别.下面是抄过来的,加了一点注释. hadoop2.0已经发布了稳定版 ...