03-类与对象——课后动手动脑
1.早期我们经常这样定义变量
int value=100;
前面的示例中这样定义变量
MyClass obj = new MyClass();
这两种方式定义的变量是一样的吗?
这两种方式定义的变量是一样的,因为它们都是类的实例化,只是第一种是一个简便的写法,第二种是正常的对类进行实例化。
2.对象变量也可以使用“==”判断两变量值是否相等吗?
当“==”施加于引用类型变量时,是比较这两个变量是否引用同一对象,换句话说,“==”实际上相当于比较两个引用类型变量中保存的对象地址是否相同。
在Java中要比对两个对象的字段值,可以重写基类的equals()方法。将其改成自己类的一个方法用来调用。
3.请输入并运行以下代码,得到什么结果?
public class Test {public static void main(String[] args) {Foo obj1=new Foo();Foo obj2=new Foo();System.out.println(obj1==obj2);}} class Foo{int value=100; }
运行结果:
原因:按照第2条,我们可知,“==”实际上相当于比较两个引用类型变量中保存的对象地址是否相同。obj1和obj2虽然都是Foo类型的变量,但其指向的空间或者地址不同,所以输出的是false。
4.
请总结一下,这个方法有哪些“与众不同之处”,你能列出几条?
1.方法名与类名完全相同。
2.无返回值,也没有void关键字。
5.以下代码为何无法通过编译?哪儿出错了?
原因:在类中如果提供了一个构造函数,那么在进行类的实例化时,调用的就是这个构造函数。此例中,Foo类本身提供了一个有参构造函数,这就导致系统不会提供默认的构造函数,那么定义obj1时就无法调用无参构造函数,所以整个程序当中会出现错误。
6.如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,谁说了算?
例:
1 public class InitializeBlockClass { 2 3 { 4 5 field = 200; 6 7 } 8 9 public int field = 100; 10 11 public InitializeBlockClass(int value){ 12 13 this.field = value; 14 15 } 16 17 public InitializeBlockClass(){ 18 19 } 20 21 public static void main(String[] args) { 22 // TODO Auto-generated method stub 23 InitializeBlockClass obj = new InitializeBlockClass(); 24 25 System.out.println(obj.field); 26 27 28 obj = new InitializeBlockClass(300); 29 30 System.out.println(obj.field); 31 32 } 33 34 }
运行结果:
Java字段初始化的规律:
如果有多个不同地方对字段进行初始化,那么该字段的最终取值取决于最后一次初始化。
7.请运行TestStaticInitializeBlock.java示例,观察输出结果,总结出“静态初始化块的执行顺序”。
TestStaticInitializeBlock.java
1 class Root 2 { 3 static{ 4 System.out.println("Root的静态初始化块"); 5 } 6 { 7 System.out.println("Root的普通初始化块"); 8 } 9 public Root() 10 { 11 System.out.println("Root的无参数的构造器"); 12 } 13 } 14 class Mid extends Root 15 { 16 static{ 17 System.out.println("Mid的静态初始化块"); 18 } 19 { 20 System.out.println("Mid的普通初始化块"); 21 } 22 public Mid() 23 { 24 System.out.println("Mid的无参数的构造器"); 25 } 26 public Mid(String msg) 27 { 28 //通过this调用同一类中重载的构造器 29 this(); 30 System.out.println("Mid的带参数构造器,其参数值:" + msg); 31 } 32 } 33 class Leaf extends Mid 34 { 35 static{ 36 System.out.println("Leaf的静态初始化块"); 37 } 38 { 39 System.out.println("Leaf的普通初始化块"); 40 } 41 public Leaf() 42 { 43 //通过super调用父类中有一个字符串参数的构造器 44 super("Java初始化顺序演示"); 45 System.out.println("执行Leaf的构造器"); 46 } 47 48 } 49 50 public class TestStaticInitializeBlock 51 { 52 public static void main(String[] args) 53 { 54 new Leaf(); 55 56 57 } 58 }
执行结果:
“静态初始化块的执行顺序”:
1.静态初始化块只执行一次。
2.创建子类型的对象时,也会导致父类型的静态初始化块的执行。
8.静态方法中只允许访问静态数据,那么,如何在静态方法中访问类的实例成员(即没有附加static关键字的字段或方法)?
在静态方法中使用new进行实例化,然后再调用非静态成员。
例:
1 public class Task { 2 3 public int a = 2; 4 5 static int b = 3; 6 7 static void display() 8 9 { 10 11 Task t1 = new Task(); 12 13 System.out.println("a="+t1.a); 14 15 } 16 public static void main(String[] args) { 17 // TODO Auto-generated method stub 18 Task t2 = new Task(); 19 20 t2.display(); 21 22 } 23 24 }
执行结果:
9.请看以下的神奇代码:
public class StrangeIntegerBehavior { public static void main(String[] args){Integer i1=100;Integer j1=100;System.out.println(i1==j1);Integer i2=129;Integer j2=129;System.out.println(i2==j2);}}
执行结果:
两对整数明明完全一样,为何一个输出true,一个输出false?
首先,利用javap对该程序进行反汇编。结果如图:
可以看到其调用了Integer中的valueOf方法,valueOf方法的源代码为:
可以看到,valueOf(int i)调用了IntegerCache.cache,通过网上查找,我得到了它的源代码如下:
1 private static class IntegerCache { 2 static final int low = -128; 3 static final int high; 4 static final Integer cache[]; 5 6 static { 7 // high value may be configured by property 8 int h = 127; 9 String integerCacheHighPropValue = 10 sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); 11 if (integerCacheHighPropValue != null) { 12 try { 13 int i = parseInt(integerCacheHighPropValue); 14 i = Math.max(i, 127); 15 // Maximum array size is Integer.MAX_VALUE 16 h = Math.min(i, Integer.MAX_VALUE - (-low) -1); 17 } catch( NumberFormatException nfe) { 18 // If the property cannot be parsed into an int, ignore it. 19 } 20 } 21 high = h; 22 23 cache = new Integer[(high - low) + 1]; 24 int j = low; 25 for(int k = 0; k < cache.length; k++) 26 cache[k] = new Integer(j++); 27 28 // range [-128, 127] must be interned (JLS7 5.1.7) 29 assert IntegerCache.high >= 127; 30 } 31 32 private IntegerCache() {} 33 }
通过这两段代码,我们可知,在[-128,127]这个区间中“”==”比较的是这两个数的数值,但当超出这个范围时,其就会创建一个新的对象,对于对象来说,我们是无法通过“==”进行比较的,因为“==”比较的是这两个对象所指向的空间是否相同,所以第二个会输出false。
转载于:https://www.cnblogs.com/guo-xu/p/7688886.html
03-类与对象——课后动手动脑相关推荐
- java/03/类与对象,深入分析类与对象(权限修饰,构造方法和简单java类),数组的定义及使用
java/03/类与对象,深入分析类与对象(权限修饰,构造方法和简单java类),数组的定义及使用 七十年代,IBM的Smalltalk语言最先推广面向对象,后来C语言变为C++,后来C++又产生了J ...
- java 类及对象的课后作业_JAVA类和对象课后作业
1.使用类的静态字段和构造函数,我们可以跟踪某个类所创建对象的个数.请写一个类,在任何时候都可以向它查询"你已经创建了多少个对象?" 代码: //显示类 //YiMingLai 2 ...
- 类与对象- 课后作业1
1 . 题目要求: 使用类的静态字段和构造函数,我们可以跟踪某个类所创建对象的个数.请写一个类,在任何时候都可以向它查询"你已经创建了多少个对象?". 2 . 设计思路: 首先在类 ...
- 04-String课后动手动脑
一.String.equals()方法 public final class String implements java.io.Serializable, Comparable<String& ...
- Pyf20230324(Python类和对象)
01 编程思维 根据面对问题不同人层显出来的思维模式不同,可以将编程思维分为三种: 1.面向过程编程(穷人思想) - 遇到问题马上想到是解决这个问题的具体逻辑和步骤 2.函数式编程(小资思想) - 遇 ...
- 04_类与对象_课程动手动脑问题以及课后实验性问题及解答集锦
Answer: 动手动脑: 1--以下代码为何无法通过编译?哪儿出错了? Answer: 因为类Foo的构造函数是有一个参数的,所以我们在new一个Foo类的对象时必须赋予一个符合条件的实参. 2-- ...
- JAVA语法基础 动手动脑及课后作业
动手动脑1: 仔细阅读示例: EnumTest.java,运行它,分析运行结果? public class EnumTest { public static void main(String[] ar ...
- JAVA语法基础作业——动手动脑以及课后实验性问题(一)
一.枚举类型 public class EnumTest { public static void main(String[] args) { Size s=Size.SMALL; Si ...
- 03-方法ppt动手动脑问题及课后实验性问题总结
一.如何不使用static来进行调用函数? 1.自己定义的不需要都是static,但是要在主函数中调用就需要static了,因为main是静态 的,在类加载时就加载了.如果想用又不加可以吧自己写的方法 ...
最新文章
- Object-C 如何把一个时间戳转换为一个标准的时间格式?
- 使用SharedPreferences进行数据存储
- python处理文本格式_python linecache 处理固定格式文本数据的方法
- 【教程】Linux下MySQL 8.0安装配置
- Python logging模块日志存储位置踩坑
- js操作DOM对象(节点的增删改)
- sessionStorage什么时候失效
- Bootstrap 标签导航的布局
- linux 文本操作
- UiPath如何实现暂停功能?
- 若干小球碰撞的一种暴力解题法
- 微信公众号图文消息悄悄调整,注定10月12号是个不眠夜
- 陀螺世界脚本合集分享,autojs弹窗代码、autojs多选勾选代码
- 微软雅黑字体包替换XP的宋体(附下载)
- [Unity热更新]tolua# LuaFramework(七):lua使用DOTween
- java获取工作日 日历接口_节假日api接口之获取指定日期的节假日信息
- 自定义控件其实很简单2
- Servlet是什么?
- 5G专网核心网部署模式与挑战
- 抖音世界杯直播时出现男女“不雅”声音?官方回应了!