课程作业02:将课程中的所有动手动脑的问题以及课后实验性的问题,整理成一篇文档。
1、质疑:一个Java类文件中真的只能有一个公有类吗?请依据你的试验结果调整前页的描述,使其更为准确,后面的课程中将学习接口(interface),这里关于公有类的结论是否同样可用于接口?
内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。这一点和外部类有一点不一样,外部类只能被public和包访问两种权限修饰。上面的例子,如果成员内部类Inner如果用public修饰,则任何地方都能访问。
所以,java源文件中直接定义的public类只能有一个,且该类名必须与源文件名一致。但内部类可以理解为外部类的一个成员,成员可以用public修饰。
同样的,对于接口而言,一个java文件可以写多个类和接口在里面,但必须只能且必须有一个public接口,而且那个public的接口必须和文件同名。
2、把main()方法的返回值由 void 改为 int ,程序能编译通过吗?能运行吗?
不行,必须返回int类型的结果。
3、为什么java规定作为程序入口点的main() 方法静态的?
非静态成员函数在执行前必须要先构造并实例化该函数所在的类。
若允许非静态的main函数,那么必须先实例化main函数所在的类。就又需要再去写个函数用来实例化main函数所在的类,再调用main函数。而且如果这个实例化代码也是非静态的,又要再写个函数去实例化它所在的类。
依次下去,将可能无限循环,所以java语言就规定了main必须是静态的。
4、请看左边的示例代码,输出结果是什么?
1 public class text 2 { 3 private static int value=1; 4 public static void main(String[] args) 5 { 6 int value=2; 7 System.out.println(value); 8 } 9 }
结果为2
5、Java变量遵循“同名变量的屏蔽原则”,请课后阅读相关资料弄清楚相关知识,然后自己编写一些测试代码,有意识地在不同地方定义一些同名变量,看看输出的到底是哪个值。
1 public class text 2 { 3 private static int value=1; 4 final private double x=1; 5 public static void main(String[] args) 6 { 7 int value=2; 8 double x=2; 9 System.out.println(value); 10 System.out.println(x); 11 } 12 }
结果为 2 1
在代码中,第一个value是成员变量,也是全局变量,第二个value是局部变量,局部变量可以覆盖全局变量。而第一个x是终端变量,这个时候第二个x便不可更改。
在使用变量时需要遵循的原则为:就近原则。首先在局部范围找,有就使用;接着在成员位置找。然后在主函数里面创建对象并输出。
成员变量和局部变量的区别:
成员变量:定义在类中,在整个类中都可以被访问,随着对象的建立而建立,随着对象的消失而消失,且有默认初始化值。
局部变量:只定义在局部范围内,如:函数内,语句内等,只在所属的区域有效。作用的范围结束,变量空间会自动释放,并且局部变量没有默认初始化值
6、看着这个图,再查查Java中每个数据类型所占的位数,和表示数值的范围,你能得出什么结论?
byte:8位,最大存储数据量是255,存放的数据范围是-128~127之间。
short:16位,最大数据存储量是65536,数据范围是-32768~32767之间。
int:32位,最大数据存储容量是2^32-1,数据范围是-2^31~2^31-1。
long:64位,最大数据存储容量是2^64-1,数据范围为-2^63次~2^63-1。
float:32位,数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F。
double:64位,数据范围在4.9e-324~1.8e308,赋值时可以加d或D也可以不加。
boolean:只有true和false两个取值。
char:16位,存储Unicode码,用单引号赋值。
结论:int类型转化为float,double 有精度损失, long转化为double时有精度损失。
7、为什么double类型的数值进行运算得不到“数学上精确”的结果?
结果与浮点数在计算机内部的表示方法有关系,这种方法问题在于如何在二进制中保存小数点的问题,即利用科学计数法,这样来保证小数点在第一个位置。由于计算机只能处理0和1,所以在计算机里面表示浮点数的时候,科学计数法中的基数是2,而不是10。所以说计算机里面浮点数都是近似值,而不是确切的值。
计算机得出的的数值,在大多数情况下需要比64bit更多的位数才能准确表示出来(甚至是需要无穷多位),而double类型的数值只有64bit。因此后面舍去的位数一定会带来误差,无法得到“数学上精确”的结果。
8、在构建BigDecimal对象时应使用字符串而不是double数值,否则,仍有可能引发计算精度问题。(为什么会这样呢?)
double并不能准确的代表BigDecimal 16位有效数以上的数字在使用BigDecimal时创建对象。而BigDecimal所创建的对象不能使用+-*/等传统的算术运算符直接对其对象进行数学运算,必须调用相对应的(f1.add(f2))等方法。
因为方法中的参数必须是BigDecimal的对象,所以定义时应为字符串。
9、以下代码输出什么?以下代码的输出结果是什么?
1 int X=100; 2 int Y=200; 3 System.out.println("X+Y="+X+Y); 4 System.out.println(X+Y+"=X+Y");
输出结果:
X+Y=100200
300=X+Y
为什么会有这样的输出?
因为输出的是字符串,在语句一中,“+”直接连接两个字符;而在语句二中,“+”先是进行数值类型的求和运算,再用字符串输出两个整形的和。