课后作业——2022.09.10
1、JAVA的基本运行单位是类还是方法?
Java 程序的基本单位是类,你建立类之后,就可用它来建立许多你需要的对象。Java把每一个可执行的成分都变成类。
2、类由什么组成?
类的构成包括成员属性和成员方法(数据成员和成员函数)。
数据成员对应类的属性,类的数据成员也是一种数据类型,并不需要分配内存。
成员函数则用于操作类的各项属性,是一个类具有的特有的操作。
类和外界发生交互的操作称为接口。
3、变量的类型,相互之间可以转换吗,浮点数?
可以,但不同变量类型之间发生转换时要注意会有误差的出现。
4、String是一个数据类型吗?
Java中的字符串String属于引用数据类型。
5、static代表的含义?
Java中,static含义为属于类但不属于类对象的变量和函数,static表示“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,或者进行静态导包。
static的特点:1、随着类的加载而被加载;2、优先于对象存在;3、被所有对象共享。
6、仔细阅读示例: EnumTest.java,运行它,分析运行结果?
你能得到什么结论?你掌握了枚举类型的基本用法了吗?
1)源代码:
public class EnumTest {
public static void main(String[] args) {
Size s = Size.SMALL;
Size t = Size.LARGE;
System.out.println(s == t); //
System.out.println(s.getClass().isPrimitive());
Size u = Size.valueOf("SMALL");
System.out.println(s == u); // true
for (Size value : Size.values()) {
System.out.println(value);
}
}
}
enum Size {
SMALL, MEDIUM, LARGE
};
2)运行结果:
3)分析和总结用法
枚举类型的使用是借助enum这样一个类,这个类是JAVA枚举类型的公共基本类。枚举目的就是要让某个变量的取值只能为若干固定值中的一个。
1.Size s=Size.SMALL;
对s变量进行赋值,只能给已经定义好的常量(即SMALL,MEDIUM,LARGE中的其中一个)。
2.System.out.println(s==t);
判断s是否与t相同,并输出判断结果(true/false)。
3.System.out.println(s.getClass().isPrimitive());
调用enum中的方法,返回Class类型的对象,检查此Class对象是否表示原始类型(true/false)。
4.Size u=Size.valueOf("SMALL");
对u进行赋值,与1相似,使用不同的赋值语句。
5.System.out.println(s==u);
判断s是否与u相同,并输出判断结果(true/false)。
6.for(Size value:Size.values())
{
System.out.println(value);
}
对枚举进行遍历。
7.enum Size{SMALL,MEDIUM,LARGE};
表明使用类ENUM,名字叫Size,其中有元素SMALL,MEDIUM,LARGE,这几个元素可以看做类中的对象。
7、动脑动手1:
阅读相应教材,或者使用互联网搜索引擎,弄清楚反码、补码跟原码这几个概念,然后编写示例程序,对正数、负数进行各种位操作,观察输出结果,与手工计算的结果进行比对,看看Java中的数是采用上述哪种码表示的。
1) 原码
原码就是符号位加上真值的绝对值,即用第一位表示符号,其余位表示值。比如:如果是8位二进制:
[+1]原 = 0000 0001
[-1] 原 = 1000 0001
第一位是符号位,因为第一位是符号位,所以8位二进制数的取值范围就是:(即第一位不表示值,只表示正负。)
[1111 1111 , 0111 1111]
即
[-127 , 127](PS:64+32+16+8+4+2+1=127)
原码是人脑最容易理解和计算的表示方式。
2)反码
反码的表示方法是:
正数的反码是其本身;
负数的反码是在其原码的基础上,符号位不变,其余各个位取反。
[+1] = [0000 0001]原= [0000 0001]反
[-1] = [1000 0001] 原= [1111 1110]反
可见如果一个反码表示的是负数,人脑无法直观的看出来它的数值。通常要将其转换成原码再计算。
3)补码
补码的表示方法是:
正数的补码就是其本身;
负数的补码是在其原码的基础上,符号位不变,其余各位取反,最后+1。(也即在反码的基础上+1)
[+1] = [0000 0001]原 = [0000 0001]反= [0000 0001]补
[-1] = [1000 0001] 原 = [1111 1110] 反= [1111 1111]补
对于负数,补码表示方式也是人脑无法直观看出其数值的。通常也需要转换成原码再计算其数值。
int a=9;
int b=-9;
int sum=a+b;
System.out.println(sum);
易知程序的结果为0。
原码:(00001001)原+(10001001)原=(10010010)原,换算成十进制为-18,与结果不符。
反码:(00001001) 反+ (11110110)反 = (11110111)反,换算成十进制为8,与结果不符。
补码:(00001001)补 + (11110111)补 = (11111111)补 ,换算成十进制为0,与结果符合。
故在java中,数是由补码表示的。
8、示例:两数相加
9、动脑动手2:
Java变量遵循“同名变量的屏蔽原则”,请课后阅读相关资料弄清楚相关知识,然后自己编写一些测试代码,就象本示例一样,有意识地在不同地方定义一些同名变量,看看输出的到底是哪个值。
1)代码:
public class Test {
private static int A= 1;
public static void main(String[] args) {
int A = 7;
System.out.println(A);
}
}
2)结果:
7
对于同名变量,若变量是在局部内定义并使用,那么将不适用全局变量,而使用局部变量的值。
若变量是在全局定义并使用,那么将屏蔽局部变量,而使用全局变量的值。
看着这个图,再查查Java中每个数据类型所占的位数,和表示数值的范围,你能得出什么结论?
整型: byte(8),short(16),int(32),long(64)
浮点型: float(32), double(64)
java自动完成从低级类型向高级类型转换,即取值范围相对较小的数据类型转换成取值范围相对较大的数据类型。
11、动手实验1:
请运行以下代码(TestDouble.java)
你看到了什么样的输出,意外吗?
不意外。
为什么double类型的数值进行运算得不到“数学上精确”的结果? 请通过互联网查找资料,或者是阅读相关计算机教材,解决这个问题。
事实上浮点运算很少是精确的,只要是超过精度能表示的范围就会产生误差。往往产生误差不是 因为数的大小,而是因为数的精度。因此,产生的结果接近但不等于想要的结果。尤其在使用 float 和 double 作精确运 算的时候要特别小心。可以考虑采用一些替代方案来实现。如通过使用 long 类型来转换。我们知道在计算机中浮点数的表示方法是由一个整数(即尾数)乘以一个基数(计算机中一般为2)的整次幂得到。(类似于科学计数法,科学记数法基数为10)float的内存结构为:符号位表示正负,1位 指数位,8位 尾数位,32位(符号位1表示负,0表示正)指数是以2为底的,范围是 -128 到 127,如果超过了127,则从-128开始计。 即:127+1=-128尾数都省去了第1位的1,所以在还原时要先在第一位加上1。它可能包含整数和纯小数两部分,也可能只包含其中一部分,视数字大小而定。对于带有整数部分的浮点数,其整数的表示法有两种,当整数大于十进制的16777215时使用的是科学计数法,如果小于或等于则直接采用一般的二进制表示法。科学计数法和小数的表示法是一样的。小数部分则是直接使用科学计数法,形式是X * ( 2 ^ n )。这样就导致浮点类型在计算机的存贮中无法精确表示。(百度查阅)
12、在构建BigDecimal对象时应使用字符串而不是double数值,否则,仍有可能引发计算精度问题。(为什么会这样呢?)
原因是double不能表示为任何有限长度的二进制小数。
13、动手动脑2
以下代码的输出结果是什么?
int X=100;
int Y=200;
System.out.println("X+Y="+X+Y);
System.out.println(X+Y+"=X+Y");
为什么会有这样的输出结果?
输出结果:
原因:
“+"只有在两个String类型中或者其中一个是string类型中的时候才起到连接作用,不然只能是运算符。
在system.out.println()中,如果在string字符串后面是+和变量,会把变量转换成string类型,加号起连接作用。