Java学习笔记门外篇:数据类型
来源:互联网 发布:淘宝如何上传宝贝视频 编辑:程序博客网 时间:2024/06/05 18:56
一、类 型
1.范围与转换相关
数据类型 关键字 内置类 范围 占字节 默认值 字节型 byte Byte -27 ~ +27=-128~127 1字节: 8bit 0 短整型 short Short -215~+27 2字节: 16bit 0 整型intInteger-231~+231 4字节: 32bit 0 长整型 long Long -263 ~ +263 8字节: 64bit 0L 字符型 char Character JDK1.8中Java的字符采用Unicode6.2编码,JVM采用UTF-16Big Endian。
Unicode范围为‘\u0000’到‘\uffff’,
整数范围是0~65535。
例如,65代表‘A’,97代表‘a’2字节: 16bit ‘\u0000’
Null 单精度浮点型 float Float Float.MIN_EXPONENT:-126 ~ Float.MAX_EXPONENT:127 4字节: 32bit 0.0F 双精度浮点型double DoubleFloat.MIN_EXPONENT:-1022 ~ Float.MAX_EXPONENT:1023
(浮点数默认为double)8字节:64bit 0.0D 字符型 boolean Boolean false & ture 1字节: 8bit false 类 className各类类型的类名 Null
2.符号的简要使用
格式控制符与算术运算符
像这类符号可以举出非常多到用时查找即可在此仅仅列出部分
3.进制转换与表示格式
举个例子一目了然 :
int number1 = 12;//十进制 int number2 = 014;//八进制 int number3 = 0xc;//十六进制 //浮点数除用小数表示还可用科学记号法表示 double number4 = 0.00123; double number5 = 1.23e-3; //若要表示字符,则需要使用“'”符号 char size = 'M'; char name = '麦克喵'; //对于常量的一种表示方法,为使表示更加清晰 int number7 = 1234_5678; double PI = 3.141_592_653;
4.使用java.util.Scanner与java.math.BigDecimal标准类
1.使用java.util.Scanner
如果是要在命令提示符模式下取得用户输入,基本上可以使用System.in对象的read()方法,不过这个方法返回int类型。
此时可以通过Scanner来代劳:
import java.util.Scanner;//导入类,以下即可简写Scanner scan = new Scanner (System.in);//建立Scanner实例int num = scan.nextInt();//获取输入的下一个整数
Scanner的nextInt()方法会先看看标准输入中有无下一个字符串(以空格或换行符分隔),有的话则尝试剖析为int类型,Scanner对每个基本类型都有对应的next__( )方法,如nextByte()、nextDouble()等,如果是直接取得字符串,则使用next(),如果取得用户输入的整行文字(以换行分隔),则使用nextLine()。
2.使用java.math.BigDecimal()
- 由于Java遵循IEEE754浮点数运算规范,使用分数与指数表示浮点数,如0.75会用1/2+1/4表示,0.875会用1/2+1/4+1/8来表示,而0.1会1/16+1/32+1/256+1/512+1/4096+1/8192无限循环下去,无法精确表示而造成运算误差。所以1.0-0.8d 结果在Java、Python、JavaScript语言中也并非得到0.2。故当需要精确计算时要小心使用浮点数,而且也不要用==来比较浮点数运算结果。
- 由上,为了获得更好的精确度,可以使用BigDecimal标准类,它提供有plus()、subtract()、multiply()、divide()方法进行加减乘除运算,add()加运算,equals()比较两个BigDecimal实质上是否相同。
import java.math.BigDecimal;BigDecimal operand1 = new BigDecimal("1.0");BigDecimal operand2 = new BigDecimal("0.8");BigDecimal operand3 = new BigDecimal("0.2");BigDecimal num = new BigDecimal("2.0");BigDecimal result = operand1.subtract(operand2);if(op1.add(op2).add(op3).equals(num)){ System.out.println("op1、op2、op3的和等于num"); }
4.对象指定与相等性
Java并非完全的面向对象程序语言,在Java中有两大类型系统,即基本类型和类类型 。初学者必须区分=,==运算用于基本类型和类类型的不同。
- 当=用于基本类型时,是将值赋给变量,当==用于基本类型时,是比较两个变量所储值是否相等。
- 当在操作对象时,=是表示指定名称adc参考自某个对象,==是指比较两个名称是否参考自同一个对象。!=恰相反,表示两个对象参考自不同对象。
- 从内存的实际运作方面来看,用于基本类型和对象类型,并无不同,都用作比较两个单元引用是否来自同一个地址。
- 进一步的,若比较不同对象或者相同对象的内容值而不关注对象参考时,所用的操作equals()方法更加合适。
二、类类型
1.自动装箱
使用基本类型是出于效率,但更多时候需要基本类型像对象一样被操作。
使用Long、Integer、Double、Float、Boolean、Byte、Short、Character等类打包器。Wapper将基本类型打包到对象中,特殊的Number类对所有类型进行一般化的自动装箱(多态),示例如下:
int data = 20;Integer wrapper1 = new Integer(data);//使用new新建打包器对象int i = 20;Integer wrapper2 = i;//进一步使用自动装箱功能Integer wrapper3 = 15;int wrap3 = wrapper3;//自动拆箱Double val = wrapper3.doubleValue()/3//操作Integer类的doubleValue方法将打包值以double类型返回System.out.println(wrapper1.compareTo(wrapper2));//操作打包器方法与另一个对象的值进行比较,相同返回0,小于返回-1,大于返回1Number num = 2.71828f;//使用一般化Number类Integer i = 10;System.out.println(i+10);//i会自动拆箱进行加法运算输出20System.out.println(i++);//i会先自动拆箱先输出10,再自增运算
2.自动拆箱内幕
自动装拆箱其实是一种编译程序语法糖(Compiler Sugar),通过将一些步骤的操作封装到类中达到简化使用的效果。
引入: 当我们如下操作时程序运行结果会出现不同
Integer i1 = 100; Integer i2 = 100; System.out.println((i1 == i2)? "ture":"false");//返回ture Integer i3 = 200; Integer i4 = 200; System.out.println((i3 == i4 )?"ture":"falst");//返回false
代码不过是将100改到200但执行的效果却不同,那么这个自动装箱语法糖究竟干了什么?实际上程序会使用Integer.valueof()来建立Integer实例,调用Integer类中的valueof()方法,源码如下
public static Integer valueof(int i){ if(i>=IntegerCache.low && i<=IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i);}
很明显,通过自动装箱到Integer过程中,判断了一个IntegerCache的范围值,Integer的缓存(Cache),默认为byte的可改范围内(-128~127),在此范围内,若有已分配有同值的实例,新的实例并不会分配新的空间储值,而是直接引用已有实例的空间地址。而在超过此范围时都会重新生成新的实例。
故,在比较类类型的值时,使用equals()方法更具有保险性。
3.特殊的类类型
enum:枚举类关键字,enum定义了特殊的类继承自java.lang.Enum;其实也是Java中的一种语法糖。
public enum Action{ A,B,C,D}//反编译//注意:直接继承自Enum类的程序会被编译器拒绝这里模拟反编译import java.lang.Enum;public final class Action extends Enum{ private Action(String s, int i){ super(s,i);}//类构造器权限private,只有内部能实例化 public static final Action A; public static final Action B; public static final Action C; public static final Action D; //将存入的值定义为静态常量方便实例化后调用 ... static{//在静态代码块中实例化为带序号的对应名称对象 A = new Action("A",0); B = new Action("B",0); C = new Action("C",0); D = new Action("D",0); ... }}
在使用时,可直接当作静态常量调用,当方法定义为接收此类类型的参数时,传入时只能输入声明时定义几个的常量。
三.对象初步
1.数组对象
数组:用来接收数据,具有索引的数据结构。
int[] array1 = {1,15,45} ;//声明有三个元素空间的数组并赋初始值int[] array2 = new int[2];//声明2个连续空间的int数组 array2[0] = 45; array2[1] = 782;int[] array3 = new int[]{46,4564,4546,87} for(int i = 0;i<array1.length;i++){//利用for循环获取数组中的值 if (myList[i] > max) //获取最大值 max = array1[i]; } System.out.println(max);for(int s:array2){//增强型for循环是一种语法糖 int total += s; //计算元素之和 System.out.println(total); }int[][] array3 = int[2][3];//多维数组的声明int[][] array4 = {{147,848,456},{546,787,834,628,952}};//多维数组可看作矩阵,显然它并不完全是,实际上你也可以建立不规则数组int[][] array5 = new int[2][]; array5[0] = new int[]{54,66,48}; array5[1] = new int[]{45,465,62,89};
- 既然数组也是对象,int[]即是类名称,new方法即创建了int类型的数组实例,即int[]类的对象
- 多维数组也可理解为int[]类型的一维数组实例,即int[][]的对象.这样就理解了数组的多维实际上是一维数组的嵌套层叠
- 使用new新建一个数组时,其每个索引元素都会有默认值(参见本文第一部分)。若默认值需更改,可使用java.util.Arrays的fill()方法来设定新建数组的默认值。
- 特别注意:当声明一个类数组时,
eg:Integer[] arr = new Integer[3];
只声明容量而未赋值的时候,实际上并没有创建出任何对象。多维情况时同样适用。
2.数组复制
在Java中,数组自建立时长度即固定,若长度不够使用,需另建新的数组将原数组复制至新数组中。
浅层复制(Shallow Copy)
使用System.arrayCopy()方法可对数组进行选择复制,它接收五个参数:来源数组,来源起始索引,目的数组,目的起始索引,长度。
JDK1.6以上还可用Arrays.copyOf()方法更加方便的复制数组,并自行建立新数组存储起来int[] s1 = {45,82,84,215,45,98,27,54};int[] s2 = new int[s1.length];System.arrayCopy(s1,0,s2,0,s1.length);int[] s3 = Arrays.copyOf(s1,s1.length*2);//第二个参数即为新数组长度
然而实际上,以上两种方法用在类类型声明的数组时,都是执行浅层复制,即只复制数组的指针参考,并没有实际复制出对象。当改变其中一个数组的元素,会使因其复制得到的数组的元素都改变。
- 深层复制(Deep Copy)
当我们复制对象数组时,因为每个对象实例都有各自的属性,用户需要手动将所要复制的对象属性指定到新建的数组中。
class Clothes{//定义一个对象,实例化元素添加到数组 String color; char size; Clothes(String color,char size){ this.color = color; this.size = size; }}public class DeepCopy{ public static void main(String[] args){ Clothes[] c1 = {new Clothes("red",'L'),new Clothes("blue",'M')}; Clothes[] c2 = new Clothes[c1.length]; for(int i = 0;i<c1.length; i++){ Clothers c = new Clothes(c1[i].color, ci[i].size); c2[i] = c; } c1[0].color = "yellow"; System.out.println(c2[0].color); }}
3.字符串对象
字符串本质上是打包字符数组的对象,是java.lang.String类的实例。
由于字符串在Java中是对象,所以也就拥有一些可操作的方法,像是可以使用length()方法取得字符串长度,使用charAt()取得字符串指定从0开始索引的某个字符,使用toUppercase()将原本为小写的字符串转换成大写。
如果要将字符串转换成整数、浮点数等基本类型,可以使用一下剖析方法:
4.字符串特性
- 字符串池与字符串常量:
String name1 = "麦克喵";//字符串常量String name2 = "麦克喵";String name1 = new String("麦克喵");//字符串池String name1 = new String("麦克喵");name1 = name2; //truename1 = name3; //falstname3 = name4; //falst
在Java中,为了效率考虑,以“”包括的字符串只要内容相同,无论在程序代码中出现多少次,JVM都只会建立一个Integer实例,并在字符串池中维护,直到GC清除。
即引用一个类型时,看是否创建出一个新的实例,这也是一直在强调的,只是比较实质内容的情况,尽量使用equals()方法。
不可变动字符串
在Java中,字符串对象一旦建立,就无法更改对象中的内容,而使用+连接字符串的情况,实质上是建立了一个java.lang.StringBuilder对象,它使用append()对+左右的字符串进行连接,并通过toString()方法返回String类型。
java.lang.StringBuilder是JDK1.5之后新增的类,在该版本之前,是使用java.lang.StringBuffer类,StringBuilder与StringBuffer具有相同的操作接口,在单机非多线程(Multithread)的情况下,使用StringBuilder会有较好的效率,因为StringBuilder不会处理同步(Synchronized)的问题。
参考文章:
1.关于float类型的剖析
2. 关于 Java 数组的 12 个最佳方法
3.String、StringBuffer与StringBuilder之间区别
- Java学习笔记门外篇:数据类型
- Java学习笔记--数据类型
- 【学习笔记】Java数据类型
- #学习笔记#java数据类型
- 【Java学习笔记 】数据类型(基础数据类型)
- Java学习笔记1:数据类型-基本数据类型
- java学习笔记01--数据类型
- java学习笔记4-数据类型
- java学习笔记01--数据类型
- JAVA学习笔记 基本数据类型
- Java 学习笔记(2) -- 数据类型
- JAVA学习笔记之数据类型
- 【java学习笔记s】数据类型
- JAVA学习笔记之数据类型
- java学习笔记___数据类型
- Java学习笔记之数据类型
- Java学习笔记-数据类型划分
- JAVA学习笔记2--数据类型
- 注解+动态代理实现权限拦截
- 表示数值的字符
- 计算机启动过程
- Ext JS 布局方式(Layouts)
- stm32内存空间分配学习
- Java学习笔记门外篇:数据类型
- Maven详解(四)------ 常用的Maven命令
- spring 笔记
- (五)struct event结构体
- 关于产品经理
- like查询如何有索引效果
- 二进制位运算
- LeetCode 65. Valid Number
- 最长上升连续子序列