数据类型与运算符

我们都知道Java是强类型语言,意思是每个变量和表达式在编译期间就确定了的语言。Java语言主要分为两种一种

是基本数据类型,一种是引用类型。每种类型必须先声明后使用,类型限制了他所赋予的值的不同,程序在编译时会

进行语法检查,这样会使我们的程序更加严谨,安全。

Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。

byte:

  • byte 数据类型是8位、有符号的,以二进制补码表示的整数;
  • 最小值是 -128(-2^7)
  • 最大值是 127(2^7-1)
  • 默认值是 0
  • byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一;
  • 例子:byte a = 100,byte b = -50。

short:

  • short 数据类型是 16 位、有符号的以二进制补码表示的整数
  • 最小值是 -32768(-2^15)
  • 最大值是 32767(2^15 - 1)
  • Short 数据类型也可以像 byte 那样节省空间。一个short变量是int型变量所占空间的二分之一;
  • 默认值是 0
  • 例子:short s = 1000,short r = -20000。

int:

  • int 数据类型是32位、有符号的以二进制补码表示的整数;
  • 最小值是 -2,147,483,648(-2^31)
  • 最大值是 2,147,483,647(2^31 - 1)
  • 一般地整型变量默认为 int 类型;
  • 默认值是 0 ;
  • 例子:int a = 100000, int b = -200000。

long:

  • long 数据类型是 64 位、有符号的以二进制补码表示的整数;
  • 最小值是 -9,223,372,036,854,775,808(-2^63)
  • 最大值是 9,223,372,036,854,775,807(2^63 -1)
  • 这种类型主要使用在需要比较大整数的系统上;
  • 默认值是 0L
  • 例子: long a = 100000L,Long b = -200000L。
    "L"理论上不分大小写,但是若写成"l"容易与数字"1"混淆,不容易分辩。所以最好大写。

float:

  • float 数据类型是单精度、32位、符合IEEE 754标准的浮点数;
  • float 在储存大型浮点数组的时候可节省内存空间;
  • 默认值是 0.0f
  • 浮点数不能用来表示精确的值,如货币;
  • 例子:float f1 = 234.5f。

double:

  • double 数据类型是双精度、64 位、符合IEEE 754标准的浮点数;
  • 浮点数的默认类型为double类型;
  • double类型同样不能表示精确的值,如货币;
  • 默认值是 0.0d
  • 例子:double d1 = 123.4。

boolean:

  • boolean数据类型表示一位的信息;
  • 只有两个取值:true 和 false;
  • 这种类型只作为一种标志来记录 true/false 情况;
  • 默认值是 false
  • 例子:boolean one = true。

char:

  • char类型是一个单一的 16 位 Unicode 字符;
  • 最小值是 \u0000(即为0);
  • 最大值是 \uffff(即为65,535);
  • char 数据类型可以储存任何字符;
  • 例子:char letter = 'A';。


他们都存储在Java栈内存里面,另外他们都有自己的封装器,如果想让主类型更好的去操作管理自己的值,

比如使用valueOf(),toString等,这个时候就得去使用自己的封装类型了,Java类型封装器:Double、Float、

Long、Integer、Short、Byte、Character、Boolean,对应数据类型double、float、long、int、short、byte、

char、boolean;还有你如果想传递一个int对象的引用,而不是值,那只能用封装类

JAVA在JDK5之后会进行自动装箱、自动拆箱

装箱:将基本类型转换成对象

拆箱:将对象转换成基本类型

举个简单的例子,比如我们在往集合或数组里面添加object对象的时候


在JDK1.5之前我们都需要先讲基本类型转换成对象装到list集合里面。在JDK1.5以后系统会自动帮我们装箱;

自动类型的转换

如果一个数据类型的范围要比另外一个数据类型的要小,这样转换是没有问题的,我们把这种方式称为自动

类型转换。比如byte转int,int转浮点型,这些都没有问题。

强制类型的转换

如果一个大范围的类型要转成一个小范围的类型,就如同把一个500毫升的水,装到300毫升的瓶子里面,这样

转换不是很正常,但是JAVA也允许我们这样做,强制转换的运算符是(type),不过这样会造成数据丢失,

我们也叫做缩小转换。值得注意的是八大基本类型里面boolean值只有两种表示情况,不允许和其他值进行转换。

直接量

我们把在程序中可以直接使用的类型,叫做直接量,它存储在java的常量池里面。能指定直接量的通常只有三种数据

类型,一种是基本类型,字符串类型和null类型。直接量操作很简单可以用=号直接给他赋值。这里要注意的是

系统会保证只有一个直接量存储在常量池里面,例如

String s1="hello";
String s2="hello";
String s3="he"+"llo";
System.out.println(s1==s2);
System.out.println(s3==s1);

因为常量池里面只有一个hello,所以以后的值都会指向这个常量池里面的hello,所以只要直接量的值相等,那么他们的

存储地址也一定相同。

引用数据类型

Java有 5种引用类型(对象类型):类 接口 数组 枚举 标注

引用类型:底层结构和基本类型差别较大。

其中类都有一个共同的父类就是Object,他们都可以去实现序列化接口


运算符

算术

单目:+(取正)-(取负) ++(自增1) - -(自减1)
双目:+ - * / %(取余)
三目:a>b?true:false 说明:当a大于b的时候,为true(也就是冒号之前的值),否则为false;这整个 运算符包括一个 关系运算符(可以是“>”"<""!="等等),一个“?”,一个“:”,冒号前后需要有两个 表达式或者是值或者是对象。

关系

等于符号 :==,不等于符号 :!= ,大于符号 :>, 小于符号 :<,大于等于符号 :>= ,小于等于符号 :<= 。

位与逻辑

运算符 与(&)、非(~)、或(|)、异或(^)
&:双目运算符,运算时均把运算数转换为二进制再做比较,规则:当相同的位上均为1时结果为1,否则结 果为0.如:1010&1101,转为二进制:10001001101&1111110010比较结果为:1000000转为十进制: 64所以1010&1101=64;
| :当两边 操作数的位有一边为1时,结果为1,否则为0。如1100|1010=1110
~:0变1,1变0
^:两边的位不同时,结果为1,否则为0.如1100^1010=0110
与(&&)、非(!)、或(||)

赋值

= += -= *= /= %= &= ^= |= <<= >>=

instanceof

运算符双目运算符,左面的操作元是一个对象,右面是一个类或接口。当左面的对象是右面的类(或右边类的子孙类)创建的对象、或者是右边接口的实现类(或实现类的子孙类)的对象时,该 运算符运算结果是true,否则是false。

运算符综述

Java 的 表达式就是用 运算符连接起来的符合Java 规则的式子.运算符的 优先级决定了表达式中运算执行的先后顺序.例如,x<y&&!z相当于(x<y)&&(!z),没有必要去记忆运算符号的优先级别,在编写 程序时可尽量的使用括号来实现你想要的运算次序,以免产生难以阅读或含糊不清的计算顺序.运算符的结合性决定了并列相同级别的运算符的先后顺序,例如,加减的结合性是从左到右,8-5+3 相当于(8-5)+3.逻辑否运算符 的结合性是右到左, x 相当于!(!x).表3.4是Java所有运算符的优先级和结合性。

位移

<< 带符号左移 >>带符号右移 >>> 无号右移

运算符优先级

优先级从高到低排列如下:[ ] ( ) ++ -- ! ~ instanceof * / % + - << >> >>> <> < = > \ == != &^& & || ? := op= 。

强制和转换

Java语言和 解释器限制使用强制和转换,以防止出错导致 系统崩溃。整数和浮点数 运算符间可以来回 强制转换,但整数不能强制转换成 数组或对象。对象不能被强制为基本类型。
Java中整数 运算符在整数运算时,如果 操作数是long类型,则运算结果是long类型,否则为int类型,绝不会是byte,short或char型。这样,如果 变量i被声明为short或byte,i+1的结果会是int。如果结果超过该类型的取值范围,则按该类型的最大值取模。

运算符操作

一、运算符"+",如果必要则自动把 操作数转换为String型。如果 操作数是一个对象,它可定义一个方法toString()返回该对象的String方式,例如floata=1.0print(“Thevalueofais”+a+“\n”);+ 运算符用到的例子Strings=“a=”+a;+=运算符也可以用于String。注意,左边(下例中的s1)仅求值一次。s1+=a;//s1=s1+a//若a非String型,自动转换为String型。
二、整数算术运算的异常是由于除零或按零取模造成的。它将引发一个算术异常。下溢产生零,上溢导致越界。例如:加1超过整数最大值,取模后,变成最小值。一个op= 赋值运算符,和上表中的各双目整数运算符联用,构成一个 表达式。整数关系运算符<,>,<=,>=,==和!=产生 boolean类型的数据。
三、 数组 运算符数组运算符形式如下:<expression>[<expression>]可给出数组中某个元素的值。合法的取值范围是从0到 数组的长度减1。
四、对象 运算符 双目运算符instanceof测试某个对象是否是指定类或其子类的实例。例如:if(myObjectinstanceofMyClass){MyClassanothermyObject=(MyClass)myObject;…}是判定myObject是否是MyClass的实例或是其子类的实例。
五、浮点 运算符浮点运算符可以使用常规运算符的组合:如 单目运算符++、--, 双目运算符+、-、*和/,以及 赋值运算符+=,-=,*=,和/=。此外,还有 取模运算:%和%=也可以作用于浮点数,例如:a%b和a-((int)(a/b)*b)的语义相同。这表示a%b的结果是除完后剩下的浮点数部分。只有单精度 操作数的浮点 表达式按照单精度运算求值,产生单精度结果。如果浮点 表达式中含有一个或一个以上的双精度 操作数,则按双精度运算,结果是 双精度浮点数
六、 布尔 运算符 布尔( boolean) 变量表达式的组合运算可以产生新的 boolean值,fales和true(记得是小写)。单目 运算符!是 布尔非。双目运算符&,|和^是逻辑AND,OR和XOR运算符,它们强制两个 操作数布尔值。为避免右侧 操作数冗余求值,用户可以使用 短路求值运算符&&和||。
七、用户可以使用==和!=, 赋值运算符也可以用&=、|=、^=。三元条件操作符和C语言中的一样。
八、++ 运算符用于表示直接加1操作。增量操作也可以用加 运算符和赋值操作间接完成。++lvalue( 左值表示lvalue+=1,++lvalue也表示lvalue=lvalue+1。
九、-- 运算符用于表示减1操作。++和-- 运算符既可以作为前缀运算符,也可以做为后缀运算符。双目整数 运算符是:运算符操作**+加-减*乘/除%取模&位与|位或^位异或<<左移 >>右移(带符号) >>>添零右移整数除法按零舍入。除法和取模遵守以下等式:
(a/b)*b+(a%b)==a
最后再说一下针对数据类型与运算符最喜欢问的面试题:
1.请说一下==与equals的区别?
在Java的八种基本类型里面我们用==比较的是他们的值,还有他们的内存地址是否相等,在Java八种基本类型里面没有equals这个方法,
我们需要比较复合类型(class)是否相等,用==比较的也是他们的内存地址是否相等,而用equals则比较的是他们的值是否相等。一般
在我们的类中都会重写equalus。在重写equalus的时候都会先进行判断,即两个类的内存地址是否相等,如果相等的话,那么他们的内存
反过来说,就不一定了。另外如果我们自己定义了一个类,没有重写其equals,那么就会默认的去继承父类Object类里面的equals方法,还是
比较他们两个的内存地址是否相等。
2.有人也喜欢把==和equals和hashcode放在一起比较,这里我也整理了一下;
hachcode和equals一样都是从Object里面继承过来的,我们一般重写了equals方法的时候也需要去重写hashcode方法,当然不怎么做也可以,
每一个类都会生成一个int类型的hashcode码,hashcode会给每个类产生一个索引,当我们使用hashtable集合的时候,可以提高查询存储效率。现在来对比一下他们三者。
==比较基本数据类型的值和地址>>equals比较符合类型的值和hashcode码>>hashcode比较符合类型的hashcode码;
这样来说当两个对象的值用==比较如果相等的话,那么他们的equals和hashcode码一定相等,如果两个对象用equals来
比较 相等的话,那么他们的hashcoe码一定相等,反过来就不一定了。一般用==来比较基本类型,用equals来比较复合类
型,用 到hashtable的时候才会去比较hashcode码;
3.String,StringBuffer和StringBuilder的区别?
首先从类型上来说String是字符串常量,即是不可变的,每次更改String的内容,其实也就是创建了一个新的对象,然后把
原来的引用再指向新的对象的内存区域。而String Buffer和String Builder是字符串变量,即他们的值都可以变化,每次更改
里面的值都会在原有的基础上进行扩展。
接着从运行效率上来说,运行速度最快的自然是String Builder,因为他是非线程安全的,且每次增加都会在原有的内存值上进
行扩展,操作的始终是一块内存。而且他有一个字符缓冲区,可以一边读取字符一边存储。接着是String Buffer,他和String
Builder差不多,只不过他是线程安全的,运行效率要低于StringBuilder。最后说说String,因为每次修改值都会去创建一个
新的对象,这样往往会导致性能不够高。但是如果我们使用的是直接量就不一样了,因为直接量里面的值都存放在常量池里,
所以存取速度会大于String Buffer和String Builder。
最后说说使用场景:

1.使用String类的场景:在字符串不经常变化的场景中可以使用String类,例如常量的声明、少量的变量运算。

2.使用StringBuffer类的场景:在频繁进行字符串运算(如拼接、替换、删除等),并且运行在多线程环境中,则可以考虑使用StringBuffer,

例如XML解析、HTTP参数解析和封装,如果不考虑多线程环境又需要存取速度则可以使用StringBuilder。

4.char型变量中能不能存贮一个中文汉字? 能够定义成为一个中文的,因为java中以unicode编码,一个char占16个字节,所以放一个中文是没问题的。

5. int 和 Integer 有什么区别? Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为

int提供的封装类。Java为每个原始类型提供了封装类。原始类型封装类boolean  Boolean char  Character  

byteByte short  Short  int Integer long Long float Float double Double 引用类型和原始类型的行为完全不同,

并且它们具有不同的语义。引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型

以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变

量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值