1.整形数据

byte、short、int、long,分别是1248个字节的存储量,取值范围也是依次增大的,其中int是正负21亿多;

long a = 1111222233334444L;记住后面要加上L,否则因为1111222233334444为int型,且超出int范围;

在这里插入一个面试题:

short c = 1;c = c +1;对错与否?

因为定义c为short型,c+1计算结果是int型(short型的c与int型的1相加,结果为int型),所以要强转

c=(short)c+1;

然而,对于c+=1;这个算法和(c=c+1)效果一毛一样,但是,却存在一个隐式的类型转换;

c+=1实际上是c=(short)c+1;

所以对于上面提到的:c=c+1错;c+=1对。

那么问题来了,在上面自增运算中我们可以看到,int型数据赋值给short型变量时,要进行类型强转,

按照long a = 1111222233334444L定义是看到的那样,不加L,数值默认是int型,那么short c = 1,这里

的1也应当是int型,将int型的1赋值给short型变量却不用强转,

思索再三,只能给出这样一个解释:在变量初始化赋值的时候,只要赋的值符合变量类型要求(取值范围)

就不用进行类型强转,在进行变量操作之后再进行赋值时要检查等号两边数据类型。

2.浮点型数据

float、double;分别48字节存储量,带小数点float7位小数,double15位,精度更高;

又是面试题:

float a =3.4;double b =2.4;

其实前面的float型变量的赋值时错误的,因为上面的3.4和2.4没有后缀默认是double型的,所以对于

float a = 3.4,这里初始化时将double型数据赋值给float型变量,虽然3.4满足float型数据范围要求;

但是还是要强转类型 float a = (float) 3.4;

这是浮点型数据初始化时与整形数据初始化时的区别。

3.两数运算返回值类型

只要有一个是double类型,最终返回double类型;否则,

只要有一个是float类型,最终返回float类型;否则,

只要有一个是long类型,最终返回long类型;

否则,最终返回int型。

4.Integer包装类

这里讲一个自动装箱/拆箱的问题:

自动装箱:

Integer a = 100;Integer b = 100;a==b?

这里的自动装箱,Integer a=Integer.valueOf(100);

  1. public static Integer valueOf(int i) {
  2. if (i >= IntegerCache.low && i <= IntegerCache.high)
  3. return IntegerCache.cache[i + (-IntegerCache.low)];
  4. return new Integer(i);
  5. }

我们可以看到,自动装箱实际上是调用了Integer类的valueOf方法,当传进来的值在一个区间[-128,127]时,

直接返回一个数值;所以上述a和b都是指向同一个数值IntegerCache.cache[100-IntegerCache.low];

a==b返回true。

但是当Integer c = 150;Integer d = 150;情况就不一样了;

Integer c = Integer.valueOf(150)=new Integer(150);同理d也是等于new Integer(150);

在这里补充一下,就算数值相同,使用new和运算符算出来的结果,都会占据内存中的一块新地址,所以,这里

c、d虽然数值上相同,但是它们各自指向内存中截然不同的地址,

所以c==d返回false。

自动拆箱:

Integer a = 12;------------自动装箱

int b = a;--------------------自动拆箱

我们来看看Integer类的源码:

  1. public final class Integer extends Number implements Comparable<Integer> {
  2. private final int value;
  3. public Integer(int value) {
  4. this.value = value;
  5. }
  6. public int intValue() {
  7. return value;
  8. }
  9. }

不难发现,自动装箱的时候实现了Integer a = new Integer(12);而自动拆箱的时候实际上是执行了intValue()方法;

int b = a.intVaule();

5.值/引用传递以及堆栈的概念

java开辟了两类存储区域---栈、堆:

栈:基本类型的变量(8大基本数据类型,int b 这里的b)以及对象的引用变量(String a 这里的a);

堆:new等指令创建的对象和数组(new A()---一个A类的实例化对象);

在性能上,栈的存取速度要比堆快,仅次于寄存器,并且由于栈数据的可共享性,我们看到的几乎都是对栈数据

进行操作,很少见到人对new出来的对象进行直接操作。

A a = new A();

这句代码应作如下解析:

1.调用A类的无参构造器来实例化一个A的对象new A();

2.在堆内存中开辟一块空间存放上面实例化的A对象new A();

3.在栈内存中开辟一块空间给A类的引用变量a,此时a=null;

4.最后将对象new A()在堆内存中的地址传递给引用变量a。

这就是A类的引用(变量)指向A类的(实例化)对象。

引用传递:传递的变量指向内存中的地址,所以对该变量操作的结果会直接影响内存中的数据;

值传递:传递变量的是值的拷贝,所以操作的对象也只是源值的副本,所以源值是不会发生改变的。

下面来通过一个小程序来检测一下值/引用传递:

  1. package com.eco.factory;
  2.  
  3. public class Test {
  4.  
  5. /**
  6. * 检测不同类型参数的传值方式--基本类型变量和引用变量
  7. */
  8. // 引用变量作为参数,对数据修改
  9. public void change(A a) {
  10. a.age = 20;
  11. }
  12.  
  13. // 基本类型变量作为参数,对数据修改
  14. public void change(int b) {
  15. b = 20;
  16. }
  17.  
  18. public static void main(String[] args) {
  19. Test test = new Test();
  20. int a = 5;
  21. int b = a;
  22. System.out.println("int型数据处理之前:" + a);
  23. test.change(a);
  24. System.out.println("int型数据处理之后:" + a);
  25. if (b == a) {
  26. System.out.println("数据处理前后没发生变化,所以基本类型参数是值传递");
  27. } else
  28. System.out.println("数据处理前后发生变化,所以基本类型参数是引用传递");
  29. A c = new A();
  30. c.age = 5;
  31. System.out.println("A型数据处理之前:" + c.age);
  32. int d = c.age;
  33. test.change(c);
  34. System.out.println("A型数据处理之后:" + c.age);
  35. if (d == c.age) {
  36. System.out.println("数据处理前后没发生变化,所以引用变量型参数是值传递");
  37. } else
  38. System.out.println("数据处理前后发生变化,所以引用变量型参数是引用传递");
  39. }
  40.  
  41. }
  42.  
  43. class A {
  44. public int age;
  45. }

控制台打印输出:

  1. int型数据处理之前:5
  2. int型数据处理之后:5
  3. 数据处理前后没发生变化,所以基本类型参数是值传递
  4. A型数据处理之前:5
  5. A型数据处理之后:20
  6. 数据处理前后发生变化,所以引用变量型参数是引用传递

注:

在《Java核心技术》这本书中第四章第5节提到,java只有值传递,并且用了一个swap来验证这一论

点,在我看来是有待商榷的,我们先来看看这个swap方法:

  1. package com.eco.factory;
  2.  
  3. public class Test {
  4. public void swap(A x, A y) {
  5. A temp = x;
  6. x = y;
  7. y = temp;
  8. }
  9.  
  10. public static void main(String[] args) {
  11. Test test = new Test();
  12. A a = new A("Jack");
  13. A b = new A("Tom");
  14. test.swap(a, b);
  15. System.out.println("***********************************");
  16. System.out.println("a的姓名:" + a.name);
  17. System.out.println("b的姓名:" + b.name);
  18. }
  19. }
  20.  
  21. class A {
  22. public int age;
  23. public String name;
  24. public A(String name) {
  25. this.name = name;
  26. }
  27. }

该书提出,如果java对对象采用的是引用调用(传递),那么这个swap方法就能实现数据交换的结果,

结果就该显示a的姓名是Tom,b的姓名是Jack,实际结果a 姓名依然是Jack,b依然是Tom,所以作者

得出结论:java对对象采用的不是引用传递。

那么现在,我们来对这个程序稍作修改:

  1. package com.eco.factory;
  2.  
  3. public class Test {
  4.  
  5. public void swap(A x, A y) {
  6. A temp = x;
  7. x = y;
  8. y = temp;
  9. System.out.println("a的姓名:" + x.name);
  10. System.out.println("b的姓名:" + y.name);
  11. }
  12.  
  13. public static void main(String[] args) {
  14. Test test = new Test();
  15. A a = new A("Jack");
  16. A b = new A("Tom");
  17. test.swap(a, b);
  18. System.out.println("***********************************");
  19. System.out.println("a的姓名:" + a.name);
  20. System.out.println("b的姓名:" + b.name);
  21. }
  22. }
  23.  
  24. class A {
  25. public int age;
  26. public String name;
  27.  
  28. public A(String name) {
  29. // super();
  30. this.name = name;
  31. }
  32. }

控制台打印:

  1. a的姓名:Tom
  2. b的姓名:Jack
  3. ***********************************
  4. a的姓名:Jack
  5. b的姓名:Tom

我们可以看到在swap方法内部实际上是真的实现了作者所要求的数据交换的,这一点我认为可以反驳

作者的数据没有进行交换的论点,但是到了主方法上,a的姓名又回来了,我认为这是因为在swap方法

内部定义的x,y由于是局部变量,在方法结束之后这两个变量是会被销毁的。而主方法所访问的是a、b

这两个引用变量,而非x、y这两个引用变量(因为在全局作用域也没用定义过,所以实际上也是访问不

了的)

所以我认为,java对对象采用的是引用传递,对象并不能够反映一个数据的本质,而swap方法实现了对

a对象的复制---x,方法体内部也可以看到自始至终是对这个克隆体x的各种操作,丝毫没有涉及到a对象,

这就和基本数据类型的值传递一样,自始至终都是对克隆体的操作。

值传递:以源数据的复制品为操作对象,不会改变原数据;

引用传递:以引用变量的复制品为操作对象,不会改变原引用变量,但会同步改变两个引用变量共同指向

的数据。

6.getter方法的返回值类型问题

我们通常在写一个类的getter、setter方法时都会直接用IDE工具提供的一键生成getter、setter方法,但是

当返回值类型不是基本数据类型的话,会产生一些问题:

  1. package com.eco.factory;
  2.  
  3. import java.util.Date;
  4.  
  5. public class Test2 {
  6. public static void main(String[] args) {
  7. Date date = new Date();
  8. Father f = new Father("桔子桑", date);
  9. System.out.println(f.getHirday());
  10. f.getHirday().setHours(16);
  11. System.out.println(f.getHirday());
  12. }
  13. }
  14.  
  15. class Father {
  16. private String name;
  17. private Date hirday;
  18.  
  19. public Father(String name, Date hirday) {
  20. this.name = name;
  21. this.hirday = hirday;
  22. }
  23.  
  24. public String getName() {
  25. return name;
  26. }
  27.  
  28. public Date getHirday() {
  29. return hirday;
  30. }
  31.  
  32. }

控制台打印输出:

  1. Mon Dec 25 :24:33 CST 2017
  2. Mon Dec 25 :24:33 CST 2017

我们可以看到,就算Father类的成员变量hirday是private声明,还是可以不通过setter方法来改变hirday的

值,在Java核心技术这本书中提供了一个方法:

  1. package com.eco.factory;
  2.  
  3. import java.util.Date;
  4.  
  5. public class Test2 {
  6. public static void main(String[] args) {
  7. Date date = new Date();
  8. Father f = new Father("桔子桑", date);
  9. System.out.println(f.getHirday());
  10. Date obj =(Date)f.getHirday();
  11. obj.setHours(17);
  12. System.out.println(f.getHirday());
  13. }
  14. }
  15.  
  16. class Father {
  17. private String name;
  18. private Date hirday;
  19.  
  20. public Father(String name, Date hirday) {
  21. this.name = name;
  22. this.hirday = hirday;
  23. }
  24.  
  25. public String getName() {
  26. return name;
  27. }
  28.  
  29. public Object getHirday() {
  30. return hirday.clone();
  31. }
  32.  
  33. }

控制台:

  1. Mon Dec 25 00:34:16 CST 2017
  2. Mon Dec 25 00:34:16 CST 2017

可以看到,当返回的是hirday.clone()的时候,就算对返回值如何操作,都不会对实例化对象的hirday值

作任何改变,因为红字操作的始终只是hirday的副本,对真实值丝毫没影响。

7.

java深入浅出之数据结构的更多相关文章

  1. 《Java程序设计与数据结构教程(第二版)》学习指导

    <Java程序设计与数据结构教程(第二版)>学习指导 欢迎关注"rocedu"微信公众号(手机上长按二维码) 做中教,做中学,实践中共同进步! 原文地址:http:// ...

  2. 20145205 java语言实现数据结构实验一

    数据结构实验要求 综合类实验设计3 已知有一组数据a1a2a3a4--anb1b2b3b4--bm,其中ai均大于bj,但是a1到an和b1到bm不是有序的,试设计两到三个算法完成数据排序,且把bj数 ...

  3. java中的数据结构(集合|容器)

    对java中的数据结构做一个小小的个人总结,虽然还没有到研究透彻jdk源码的地步.首先.java中为何需要集合的出现?什么需求导致.我想对于面向对象来说,对象适用于描述任何事物,所以为了方便对于对象的 ...

  4. [转]详细介绍java中的数据结构

    详细介绍java中的数据结构 本文介绍的是java中的数据结构,本文试图通过简单的描述,向读者阐述各个类的作用以及如何正确使用这些类.一起来看本文吧! 也许你已经熟练使用了java.util包里面的各 ...

  5. 详细介绍java中的数据结构

    详细介绍java中的数据结构 http://developer.51cto.com/art/201107/273003.htm 本文介绍的是java中的数据结构,本文试图通过简单的描述,向读者阐述各个 ...

  6. 20162323周楠《Java程序设计与数据结构》第六周总结

    学号 2016-2017-2 <程序设计与数据结构>第六周学习总结 教材学习内容总结 继承:从已有类派生一个新类,是面向对象程序设计的一个特点 在Java中只支持单继承,不支持多继承 继承 ...

  7. Java程序设计与数据结构导论--读后感

    与我前面所读的<Java7基础教程>相比,此书不适合自学,更适合作为教材使用. 虽然此书完整覆盖了Java的知识点和数据结构的基础问题,并且对每个部分都做了基本说明.但是因为没有深入展开, ...

  8. 20172328 2018-2019《Java软件结构与数据结构》第一周学习总结

    20172328 2018-2019<Java软件结构与数据结构>第一周学习总结 概述 Generalization 本周学习了软件质量.数据结构以及算法分析的具体内容,主要依托于所用教材 ...

  9. 20172328 2018—2019《Java软件结构与数据结构》第二周学习总结

    20172328 2018-2019<Java软件结构与数据结构>第二周学习总结 概述 Generalization 本周学习了第三章集合概述--栈和第四章链式结构--栈.主要讨论了集合以 ...

随机推荐

  1. 使用dom4j技术对xml文档进行增删改练习(一)

    整个流程如下面代码所以,并对一些重要代码意义做出详细解释: import java.io.File; import java.io.FileOutputStream; import org.dom4j ...

  2. 【一天一道LeetCode】#96. Unique Binary Search Trees

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given n ...

  3. 如何让你的web具备权限认证

    大多数Web系统都有权限需求,前面已经了解了它的整个认证过程的原理,这节将讲述如何在Tomcat中配置web资源的权限.先以Tomcat默认的认证模式Basic和默认的域UserDatabaseRea ...

  4. Asp.net中JQuery、ajax调用后台方法总结

    通过上一篇文章实例的实现,整个过程当中学习到很多知识点,了解了Jquery.Ajax在asp.net中的运用,加以总结,其实原理都是一样的,理解了一种,其他的注意很少的区别就可以了.灵活运用: 1.有 ...

  5. python 多窗口编辑

    同时打开多个文件: 1,vim filename1 filename2 在打开的多个文件中 :next 转到下个文件中 :prev 转到上个文件中 :last/:first 分别到最后一个和第一个文件 ...

  6. Linux下ipconfig分析及C语言实现

    在linux下使用ifconfigl命令能很方便的查看网卡与网线是否连通,运行ifconfig eth0命令大致输出如下: # ifconfig eth0 eth0 Link encap:Ethern ...

  7. 使用HTML5抓取 Audio & Video

    原文地址: http://www.html5rocks.com/en/tutorials/getusermedia/intro/ 本地化的文章: http://www.html5rocks.com/z ...

  8. Android电话拦截实现以及TelephonyManager监听的取消

    由于毕业设计题目涉及到电话拦截这一块.所以鼓捣了一下.遇到了一些问题,总结一下,以免忘记,也希望能帮助其他新人们. 本篇博客目的:实现电话的拦截 会遇到的问题:android studio下AIDL的 ...

  9. android ViewPager+Fragment之懒加载

    说说写这篇博客的背景吧,前两天去面试,问到一个问题说的是:比如我们首页,是有3个fragment构成的,并且要是实现作用可以滑,那么这个最好的选择就是ViewPager+fragment了,但是我们知 ...

  10. TCP/IP概述

    1) 链路层,有时也称作数据链路层或网络接口层,通常包括操作系统中的设备驱动程序和计算机中对应的网络接口卡.它们一起处理与电缆(或其他任何传输媒介)的物理接口细节. 2) 网络层,有时也称作互联网层, ...