• Java基本类型与运算


    问题及答案来源自《Java程序员面试笔试宝典》第四章 Java基础知识 4.4基本类型与运算

    1、Java提供了哪些基本数据类型?

    Java一共提高了八种原始的数据类型:byte、short、int、long、float、double、char、boolean

    基本数据类型不是对象,而是基本数据类型,这些数据类型变量在声明之后就会立刻在栈上被分配内存空间

    八种基本类型可以分为以下四类:

    • int相关:short(2字节)、int(4字节)、long(8字节)
    • float相关:float(4字节)、double(8字节)
    • boolean相关:boolean(1字节)、byte(1字节)
    • char相关:char(2字节)(unicode字符)

    另外Java还提供了对这些原始数据类型的封装类(字符类型Character、布尔类型Boolean、数值类型Byte、Short、

    Integer、Long、Float、Double)

    封装类型和原始类型的不同之处:

    • 原始类型传递参数按值传递,封装类型传递参数传的是引用
    • 类实例化时,封装类型默认值是null,原始类型默认值与它们的类型有关(比如int默认值为0)

    精度损失:

    当把高精度的变量赋值给低精度的变量时会造成精度损失,例如将double类型的数值赋值给float类型的变量

    eg:float f = 0.93; 这样会造成精度损失,正确的方法是采用强制类型转换,eg:float f = (float)0.93;

    2、什么是不可变类?

    不可变类:

    不可变类是指当创建了这个类的实例后,就不允许修改它的值,不可变类类似于常量,即只允许别的程序读,

    但是不允许别的程序进行修改

    常见的不可变类:

    基本类型的封装类(Integer、Float等)、String

    String类是不可变类,那么下面这段代码为什么可行?

    1 String s = "Hello";
    2 s += " World";
    3 System.out.println(s);

    解释:

    第2行代码中修改的只是s的引用,s由原来的指向"Hello"改成指向"Hello World",

    原来的"Hello"还存在于内存中并没有被改变

      

    3、值传递与引用传递有哪些区别?

    Java语言中参数传递有两种方式:值传递和引用传递

    值传递:

    在方法调用中,实参把值传递给形参,形参只是用实参的值初始化一个临时的存储单元,因此形参与

    实参虽然值一样,但是有着不同的存储单元,对形参的改变不会影响实参的改变

    引用传递:

    在方法调用中,传递的是对象(也可以看作是对象的地址),这是形参和实参的对象指向同一块存储单元,

    因此对形参的修改就会影响实参的值

    在Java中,原始数据类型在传递参数时按值传递,而普通对象在传递参数时按引用传递

    实例如下:

     1 public class test {
     2     public static void testPassParameter(StringBuffer ss1, int n){
     3         ss1.append(" World");     // 引用
     4         n = 8;                    //
     5     }
     6     
     7     public static void main(String[] args) {
     8         int i = 1;
     9         StringBuffer s1 = new StringBuffer("Hello");
    10         testPassParameter(s1, i);
    11         System.out.println(s1);        // Hello World
    12         System.out.println(i);         // 1
    13     }
    14 }

    Java中八种基本数据类型都是按值传递,其他所有类型都是按引用传递,由于Java中八种基本数据类型的包装类型

    都是不可变类型,因此增加了对按引用传递的理解难度,详细情况看下面的实例:

     1 public class test {
     2     public static void changeStringBuffer(StringBuffer ss1, StringBuffer ss2) {
     3         ss1.append(" World");
     4         ss2 = ss1;
     5     }
     6 
     7     public static void main(String[] args) {
     8         Integer a = new Integer(1);
     9         Integer b = a;
    10         b = new Integer(b.intValue() + 1);
    11         System.out.println(a + " " + b);    // 1 2  第10行代码实际上是创建了一个新的Integer对象
    12         StringBuffer s1 = new StringBuffer("Hello");
    13         StringBuffer s2 = new StringBuffer("Hello");
    14         changeStringBuffer(s1, s2);
    15         System.out.println(s1 + " " + s2);    // Hello World Hello
    16     }
    17 }

    由上面的实例可以看出,按引用传递实际上当修改形参中地址对应的内容时,实参会发生相应变化,但是当

    直接改变形参地址时实参不会改变,这说明了按引用传递实际上也是一种按值传递(传的是地址)

    也就是说引用传递不会改变实际参数指向的地址,但是能改变实际参数指向的地址中的内容

    4、不同数据类型的转换有哪些规则?

    背景描述:

    在Java中,当参与运算的两个变量的数据类型不同时,就需要进行隐式的数据转换,规则为从低精度向高精度转换,

    即优先级满足:byte < short < char < long < float < double,例如不同数据类型的值在进行运算时,short类型数据

    能够自动转换成int类型,int类型能够自动转换成float类型等,反之则需要通过强类型转换

    类型自动转换:

    低级数据类型可以自动转换为高级数据类型,转换规则如下:

    自动转换的注意事项:

    • char类型转换时会自动转换成其对应的ASCII码
    • byte、char、short类型的数据在参与运算时会自动转换成int型,但使用+=运算时不会产生类型转换
    • boolean类型是不能和其他数据类型相互转换的 

    强制类型转换:

    当需要从高级数据类型转换成低级数据类型时,就需要进行强制类型转换,强制类型转换如下:

    • byte =》char
    • char =》byte
    • short =》byte、char
    • int =》byte、short、char
    • long =》byte、short、char、int
    • float =》byte、short、char、int、long
    • double =》byte、short、char、int、long、float

    另外要注意进行强制类型转换可能会损失精度(高精度转换成低精度)

    5、强制类型转换的注意事项有哪些?

    Java中的+=是Java中规定的运算法,Java编译器会对其进行特殊处理,因此语句short s1 = 1; s1 += 1; 能够编译通过 

    6、运算符优先级是什么?

    7、Math类中round、ceil和floor方法的功能各是什么?

    • round:对数四舍五入
    • ceil:对数向上取整
    • floor:对数向下取整

    下面是测试代码:

     1 public class test {
     2     public static void main(String[] args) {
     3         float m = 6.4f;
     4         float n = -6.4f;
     5         System.out.println(Math.round(m));        // 6
     6         System.out.println(Math.round(n));        // -6
     7         System.out.println("===============");
     8         System.out.println(Math.ceil(m));        //7.0
     9         System.out.println(Math.ceil(n));        // -6.0
    10         System.out.println("===============");
    11         System.out.println(Math.floor(m));        // 6.0
    12         System.out.println(Math.floor(n));        // -7.0
    13         System.out.println("===============");
    14     }
    15 }

    8、++i和i++有什么区别?

    在java的执行过程中,i++和++i都直接对i进行了i=i+1的操作,

    但是不同的是i++得到的是i未进行加法操作的前的值的副本,而++i直接得到计算后的值

    比如a = i++;是将i的值赋值给a然后i的值再+1,而a=++i是将i的值+1然后再将+1后的i的值赋值给a

    示例代码:

     1 public class test {
     2     public static void main(String[] args) {
     3         int i = 1;
     4         System.out.println((i++)+(i++));        // 3
     5         System.out.println(i);                    // 3
     6         System.out.println((i++)+(++i));        // 8
     7         System.out.println(i);                    // 5    
     8         System.out.println((i++)+(i++)+(i++));    // 18
     9         System.out.println(i);                    // 8
    10     }
    11 }

    9、无符号数的右移操作 

    Java提供了两种右移运算符:>>和>>>,>>被称为有符号右移运算符,>>>被称为无符号右移运算符

    两者的区别:

    • >>在右移时,若参与运算的数为正数则在高位补0,若为负数则在高位补1
    • >>>则不同,不论参与运算的数字为正数或负数,均会在高位补0

    引申 - <<运算符和>>运算符有什么异同?

    <<运算符标识左移,左移n位表示原来的值乘2的n次方,经常用来代替乘法操作

    例如,一个数m乘以16可以表示为将这个数左移4位(m<<4)

    由于CPU直接支持位运算,因此位运算比乘法运算的效率更高

    与右移运算不同的是左移运算没有有符号和无符号的区别,在左移时,移除高位的同时在低位补0

    10、char型变量中是否可以存储一个中文汉字?

    在Java中,默认使用unicode编码方式,即每个字符(char)占用两个字节,因此char可以存储中文汉字

    String是由char组成的,但它采用了更灵活的方式存储,即英文占用一个字节,而中文一般占用两个字节

    示例代码:

     1 public class test {
     2     public static void getLen(String s){
     3         System.out.println(s + "的长度是: " + s.length() + " 所占字节数是: " + s.getBytes().length);
     4     }
     5     
     6     public static void main(String[] args) {
     7         String s1 = "hello";
     8         String s2 = "你好";
     9         getLen(s1);
    10         getLen(s2);
    11     }
    12 }

    注:在Java中,中文字符所占的字节数取决于字符的编码方式,一般情况下,采用ISO8859-1编码方式时,

    一个中文字符与一个英文字符一样只占1个字节;采用GB2312或GBK编码方式时,一个中文字符占2个字节;

    而采用UTF-8编码方式时,一个中文字符会占3个字节

  • 相关阅读:
    关于同步解释
    dll 问题 (转)
    SQL SERVER 触发器中如何调用外部程序
    SQL SERVER所有表、字段名、主键、类型、长度、小数位数等信息
    variant 和 Stream 的互換
    Variant的相关函数
    使用 wxPython 创建“目录树”(5)
    wxPython 绘图演示——模拟雷达信号图(2)
    wxpython 实现简易画板(1)
    使用 wx.tools.img2py (4)
  • 原文地址:https://www.cnblogs.com/wyb666/p/10300570.html
Copyright © 2020-2023  润新知