0%

java基础数据类型

[toc]

数据类型#

Q:java中数据类型大小会和平台是32位、64位相关吗?#

A:不相关,虚拟机原因平台兼容


Q:java中解析数据时,需要考虑处理器的大小端问题吗?(即0x1234的12是放在高地址还是低地址)#

A:不需要。java由于虚拟机的关系,屏蔽了大小端问题,需要知道的话可用 ByteOrder.nativeOrder() 查询。在操作ByteBuffer中,也可以使用 ByteBuffer.order() 进行设置:。


Q:java中short、int 、long的字节分别是多少?#

A:2、4、8


Q: float、double是多少字节?#

A:4、8


Q: java中byte、char是多少字节?C++中char是多少字节?#

A : java中是1和2, C++中char是1


Q: java中boolean类型的大小?#

A: bool类型无空间大小(来自java编程思想)
根据http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html官方文档的描述:

boolean: The boolean data type has only two possible values: true and false. Use this data type for simple flags that track true/false conditions. This data type represents one bit of information, but its “size” isn’t something that’s precisely defined.

布尔类型:布尔数据类型只有两个可能的值:真和假。使用此数据类型为跟踪真/假条件的简单标记。这种数据类型就表示这一点信息,但是它的“大小”并不是精确定义的。

贴一下书中关于布尔数据类型的描述:
img


Q: 不可变类型有哪几种?#

A: short、int、long、float、double、byte、char、boolean的?包装类型, 以及String,这9种属于不可变类型。(这只是部分,还有其他的不可变类)

不可变类型概念:里面的值的内容变了,对应的内存地址也会变化。


Q:类里的成员如果是基本数据类型, 那么会自动初始化吗?初始化成什么?#

A: 会, 初始化为0或者false。


Q: java中局部变量没初始化,会报错吗?#

A: 会


Q: 布尔类型可以强制转化成其他类型吗?#

A : 不能。 boolean b = 1或者boolean b = “true” 是不可以的


Q: 什么时候不能隐式转化?#

A: 如果会丢失精度,则不能隐式转化,比如long转int或者double转long这种。 编译器会强制我们使用强制转化


Q: 8种原始数据类型的类型优先级排序是?#

A:
(byte/short/char)<int<long<float<double
即隐式转换都是从低往高转。


Q:下面哪个是错误的?#

img
A:
B选项是错误的。
因为2个byte类型变量相加的时候,会自动转换成int类型,右边的int类型赋值给short类型便会报错。(好冷的知识)


Q:float f = 1.1;有错吗?#

A:
float浮点后面要加f。加f就代表是float类型,否则就是double类型浮点。

float f = 1.1f;
double d1 = 1.1;


Q: 布尔类型可以做加减乘除吗?#

A : 不能

Q: Integer N = 0; int n = N; 这时候会发生什么?
A: 自动拆包


Q:整型包装类型的比较,下面输出啥?#

Integer num1 = 128,num2 = 128;
System.out.println(num1==num2);

A:
输出false。
值的范围在-128~127的时候Integer可以直接用==比较大小,但是超出这个范围时,==就不管用了,要用equals。
大致原因是在那个范围,Integer的对象会直接用缓存对象,所以地址都相同。
不在那个范围,Integer对象会新生成1个对象,所以地址不同。

另一个注意点: “==” 对于对象来说,比较的是地址。


Q: java中哪2个类可以支持任意精度的整数 和任意精度的浮点数?#

A: BigInteger和BigDecimal

这2个也属于不可变类。


Q: java的数组一定需要我们手动初始化吗?#

A: 不需要,数组元素会自动初始化为null或者0或者false。


Q:java支持C++里的运算符重载吗?#

A: 不支持


Q: if(a=b) 可以吗?#

A: 不行,不能在条件表达式中放入赋值操作。除非a和b都是boolean类型。


Q: 浮点数相等的比较方式#

A:
相等的话要像下面这样

if(Math.abs(a-b))<1E-6F)

如果用浮点的a==b或者a!=b做while循环退出判断,可能会导致死循环


Q: 上面这现象的原因,你了解吗,从浮点数的原理讲一下试试#

A:
3744d5b86b6e1010d046ea4b423e635c5bdc330f

  • 1.1用二进制表示为:1.000110…xxxx…(后面表示省略)
    0.1 = 02(-1)+02(-2)+02(-3)+12(-4)+…
  • 而double类型表示小数部分只有52位,当向后计算 52位后基数还不为0,那后面的部分只能舍弃,从这里可以看出float、double并不能准确表示每一位小数,对于有的小数只能无限趋向它。
  • 在计算机 中加减成除运算实际上最后都要在计算机中转换成二进制的加运算,由此,当计算机运行System.out.println(2.00-1.10);
    时会拿他们在计算机内存中的二进制表示计算,而1.10的二进制表示本身就不准确,所以会出现0.8999999999999999的结果。

Q:下面的数组声明哪几个是对的?#

A. char[] chr1 = new char[]{‘A’,‘B’,‘C’};
B. char[] chr2 = new char[3]{‘A’,‘B’,‘C’};
C. char[][] chr3 = new char[][10];
D. char[][] chr4 = new char[10][];
E. char[] chr5 = new char[3];

A:
ADE是对的。

字符串#


Q: StringBuffer和StringBuilder的区别:#

A:
StringBuffer是线程安全的,但是慢
StringBuilder是线程不安全的(即可以多个线程同时读取他的内容),但是快。


Q:String s = “123”+“456”+“789”;对于这种静态的拼接,用StringBuffer去拼接比用String去拼接要快,对吗?#

A:
错,反编译代码后,我们发现代码是
String s = “123456789”;
因为对于静态字符串的连接操作,Java在编译时会进行彻底的优化,将多个连接操作的字符串在编译时合成一个单独的长字符串。
因此要注意StringBuffer/Builder的适用场合: for循环中大量拼接字符串。
如果是静态的编译器就能感知到的拼接,不要盲目地去使用StirngBuffer/Builder
PS:

如果是字符串变量相加,会优化成StringBuilder做append
如果是常量字符串相加, 则会直接拼接
具体可以查看这篇博文,里面有展示这2 种情况的字节码。
https://blog.csdn.net/weixin_34405557/article/details/89630362?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param


Q:下面9种字符串拼接相等的比较,输出什么结果?为什么?#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
String s1 = "Hello";
String s2 = "Hello";
String s3 = "Hel" + "lo";
String s4 = "Hel" + new String("lo");
String s5 = new String("Hello");
String s6 = s5.intern();
String s7 = "H";
String s8 = "ello";
String s9 = s7 + s8;

System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // true
System.out.println(s1 == s4); // false
System.out.println(s4 == s5); // false
System.out.println(s1 == s6); // true
System.out.println(s1 == s9); // false

A:
println(s1 == s2)输出 true
println(s1 == s3)输出 true
println(s1 == s4)输出 false
println(s4 == s5)输出 false
println(s1 == s6)输出 true
println(s1 == s9)输出 false

字符串的==操作比较的是引用地址。
如果是直接写死在代码里的常量字符串,则地址是固定的,都在常量池中。
写死的常量字符串拼接,依旧会作为常量放入常量池中。(常量池就是指,程序编译的时候,就已经知道了这个字符串)
如果是String类型的,则引用地址是堆中的string对象地址,而非常量池中地址。(因为程序编译的时候,string里的内容不一定是确定的,因此不可能会放到常量池中)
因此涉及string拼接的,都是和原先常量不等。s7和s8已经属于string对象,所以二者不属于常量拼接。
intern会试图把字符串放入常量池。

具体原因可见
https://www.cnblogs.com/syp172654682/p/8082625.html

关于常量池,更多可以见:
原始数据类型强化学习之常量池

可变参数#


Q: 方法重载时,如何选择可变参数和固定参数?像下面输出啥:#

1
2
3
4
5
6
7
8
9
10
 public static void main(String[] args) {
f(1);
}
public static void f(int ...a){
System.out.println("可变参数方法:"+Arrays.toString(a));
}

public static void f(int a){
System.out.println("固定长度 参数方法:"+a);
}

A:
输出固定长度参数方法。
原则:
如果重载方法中,固定参数方法能满足,优先用固定参数方法,不满足时再去选择可变参数方法。


662027daa06620610256ebc9a89705952ca01b0e

参考资料:#

https://www.cnblogs.com/syp172654682/p/8082625.html