设为首页 加入收藏

TOP

Java 数据类型在实际开发中应用(一)
2017-07-13 10:22:53 】 浏览:484
Tags:Java 数据 类型 实际 开发 应用

  在前边的文章中,我已经介绍了Java核心的容器IO等,现在我来说一下java中的数据类型。在java中,一切东西皆为对象(这句话意思是java中绝大数情况都用对象),极少数不是对象的,也存在与之对应的对象(比如基本数据类型存在与之对应的包装类,数组有List对象可以代替)


  Java中数据类型 主要有“基本数据类型”、“String”、“引用类型” (基本的引用类型不多做介绍,在下一篇博文中着重介绍“枚举”,也算是引用类型的一种)


   基本类型可以分为三类,字符类型char,布尔类型boolean以及数值类型byte、short、int、long、float、double。JAVA中的数值类型不存在无符号的,它们的取值范围是固定的,不会随着机器硬件环境或者操作系统的改变而改变   


Java决定了每种简单类型的大小,并不随着机器结构的变化而变化。这正是Java程序具有很强移植能力的原因之一。下表列出了Java中定义的简单类型、占用二进制位数及对应的封装器类。 


   基本类型存储在栈中,处于效率考虑,基本类型保存在栈中。延伸一下,包装类保存在堆中(注意我之前说过的-127到128之间的包装类Integer)


  Java的堆是一个运行时数据区,不需要程序代码来显式的释放,由垃圾回收来负责即可。堆的优势是可以动态地分配内存 大小,生存期也不必事先告诉编译器(因为是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据)。但缺点是,由于要在运行时动态分配内存,存取速度较慢。


  栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量数据(int, short, long, byte, float, double, boolean, char)和引用数据类型(这个和基本数据类型无关,不多做介绍)


对于成员变量和局部变量:成员变量就是方法外部,类的内部定义的变量;局部变量就是方法或语句块内部定义的变量。局部变量必须初始化。 


  简单类型数据间的转换,有两种方式:自动转换和强制转换,通常发生在表达式中或方法的参数传递时。


  当一个较"小"数据与一个较"大"的数据一起运算时,系统将自动将"小"数据转换成"大"数据,再进行运算  。


这些类型由"小"到"大"分别为 (byte,short,char)--int--long--float—double,这里我们所说的"大"与"小",并不是指占用字节的多少,而是指表示值的范围的大小 。所以byte --char--short之间不可以自动转换


 将"大"数据转换为"小"数据时,你必须使用强制类型转换。即你必须采用下面这种语句格式: int n=(int)3.14159/2;可以想象,这种转换肯定可能会导致溢出或精度的下降


    只有boolean不参与数据类型的转换  


   在实际开发中 String使用非常广泛。于是Java设计者针对String做了非常多的优化来提高效率,这虽然提高了程序的效率,但是在一定程度上也会给我们开发提高了难度,于是在Thinking in Java中单独把String当作一个章节。下面我会从整体上总结一下String,一些具体的方法可以去查询API(Java API


  new是按照面向对象的标准语法,在内存使用上存在比较大的浪费。所以String对象的创建是不需要new的(这样可以提高效率,但是如果用new创建字符串也不会报错)


  分别是 new 关键字、Class类的 newInstance 方法、Constructor类的 newInstance 方法、String对象的 clone方法、反序列化机制。但是String对象还有一种特殊的创建方式,就是通过使用  或  包裹字符序列


  用“”创建对象的时候,String对象是放到常量池中,只会创建一个,每次都是先去找一下常量池有没有该字符串


  用 new创建对象,会在队中创建一个对象,然后在栈内创建该对象应用,每次都是新创建


  String类初始化之后不可变,因为java设计者不希望我们方法传参是字符串的时候,方法内修改会影响外边的串,所以采取了一种传递拷贝的方式(也就是传值)


  java中,一旦产生String对象,该对象就不会在发生变化。但是String另一方面的确提供了修改String的方法。这看起来很矛盾,实际上是我们没有仔细的了解那些修改的方法


s的变化)


                                  


下边的代码 :我在原字符串的基础上添加了一句话,然后判断他们是否相同(如果是同一个对象修改,==输出结果应该是true)


思考一下 "s1指向的对象中的字符串是什么"(我们潜意识的认为s1也会被修改,但是当s2 = "s2"时,实际上s2的引用已经被修改,它和s1没关系了)


再重复一遍,无论是修改字符串的方法还是对字符串赋值,都和普通的对象不同。赋值是让字符串指向一个新的字符串,方法传参是copy一份值,传入进去


  再比如说:String str=”kv”+”ill”+” “+”ans”; 就是有4个字符串常量,首先”kv”和”ill”生成了”kvill”存在内存中,然后”kvill”又和” ” 生成 “kvill “存在内存中,最后又和生成了”kvill ans”;并把这个字符串的地址赋给了str


所以 + 会产生很多临时变量。下文中会说到StringBuilder 来避免这种情况。不过有一种特殊情况。 "ab"+"cd" 在JVM编译后和"abcd"一样


在String源码中 ,使用private final char value[]来实现字符串的存储,就是因为final,才说String类型是不可变


   String常量是保存在常量池中。JVM中的常量池在内存当中是以表的形式存在的, 对于String类型,有一张固定长度的CONSTANT_String_info表用来存储文字字符串值,注意:该表只存储文字字符串值,不存储符号引用。说到这里,对常量池中的字符串值的存储位置应该有一个比较明了的理解了。在程序执行的时候,常量池会储存在Method Area,而不是堆中。常量池中保存着很多String对象; 并且可以被共享使用,因此它提高了效率


  常量池指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。


除了包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值(final)还包含一些以文本形式出现的符号引用。


  总体来说,如果你还是对String感到困惑,不如把握住一点就是“ 创建时间” 如果编译期就知道是啥,会丢到常量池.


  首先StringBuilder 和StringBuffer区别是 StringBuffer线程安全(存在一堆synchronized)


  其次,我们推荐用S

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇用 jQuery.ajaxSetup 实现对请求.. 下一篇Java基本数据类型总结

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目