内容简介:我们来看一下包装类相关的比较,看下下面的代码,最终将打印什么呢?代码很简单,就是对各个包装类的几个值进行比较,可以猜测下这段代码的打印结果。这里我们直接将打印结果贴出来:如果和你的预期结果是一致的,那么说明你这里掌握的很好,而如果和你的预期结果有稍稍不同的话,那么或许你可以再接着往下看。
问题一:包装类的缓存还记得不?
我们来看一下包装类相关的比较,看下下面的代码,最终将打印什么呢?
public static void main(String[] args) { Boolean bool1 = true, bool2 = true; System.out.println("bool1==bool2 ? " + (bool1 == bool2) ); Character c1 = 127, c2 = 127; Character c3 = 128, c4 = 128; System.out.println("c1==c2 ? " + (c1 == c2)); System.out.println("c3==c4 ? " + (c3 == c4) ); Integer i1 = 10, i2 = 10; Integer i3 = 300, i4 = 300; System.out.println("i1==i2 ? " + (i1 == i2)); System.out.println("i3==i4 ? " + (i3 == i4) ); Long long1 = 10L, long2 = 10L; Long long3 = 300L, long4 = 300L; System.out.println("long1==long2 ? " + (long1 == long2)); System.out.println("long3==long4 ? " + (long3 == long4)); Float float1 = 10f, float2 = 10f; Float float3 = 300f, float4 = 300f; System.out.println("float1==float2 ? " + (float1 == float2)); System.out.println("float3==float4 ? " + (float3 == float4)); }
代码很简单,就是对各个包装类的几个值进行比较,可以猜测下这段代码的打印结果。这里我们直接将打印结果贴出来:
bool1==bool2 ? true c1==c2 ? true c3==c4 ? false i1==i2 ? true i3==i4 ? false long1==long2 ? true long3==long4 ? false float1==float2 ? false float3==float4 ? false
如果和你的预期结果是一致的,那么说明你这里掌握的很好,而如果和你的预期结果有稍稍不同的话,那么或许你可以再接着往下看。
解惑1:
首先,我们学习String的时候,都知道String类是不可变的,因此编译阶段会将String常量放入字符串常量池中,当下次使用时就可以直接从字符串常量池中提取。
而对于包装类来说,其对象同样也是不可变的。所以对于某些频繁使用的值,系统也提供了包装类的缓存,当需要时直接从缓存中取值,而不是再创建一个新的包装类对象。
这些包装类缓存的范围如下:
-
boolean的所有值(true和false);
-
char值的
0~127
; -
byte,short,int,long的
-128~127
;
以Long为例,我们来简单看一下源码:
private static class LongCache { private LongCache(){} static final Long cache[] = new Long[-(-128) + 127 + 1]; static { for(int i = 0; i < cache.length; i++) cache[i] = new Long(i - 128); } }
这个 LongCache
就是Long中缓存的实现,其他的也是类似,如 IntegerCache
, CharacterCache
等,这里比较有意思的是:
static final Long cache[] = new Long[-(-128) + 127 + 1];
这里数组的容量,使用了 -(-128) + 127 + 1
,这个我觉得写的挺有意思的,相当于是间接标识出了数组元素对应的范围:
-(-128)表示负数的元素是128个; 127 则表示正数的元素是127个, 1 则表示元素0的个数;
这里我们在写代码的时候可以参考下,而其他的Cache的实现则是类似的,大家有兴趣的可以扒下代码看看。
对于浮点类型Float和Double,包装类没有缓存。
问题二:main方法有什么特殊的呢
我们一开始学习 Java 程序的时候,最先跑的一段代码肯定是main方法,main方法的格式如下:
public static void main(String[] args)
那么main方法有什么特殊的地方呢?我们来简单看一下。
解惑2:
首先针对main方法的格式定义:
-
public:main方法是启动的时候由JVM进行加载的,public的可访问权限是最高的,所以需要声明为public;
-
static:方法的调用要么是通过对象,要么是通过类,而main方法的话因为是由虚拟机调用的,所以无需生成对象,那么声明为static即可;
-
main:至于为什么方法名称叫main,我想应该是参考的是 C语言 的方法名吧;
-
void:main方法退出时,并没有需要有相关返回值需要返回,所以是void;
-
String[]:此字符串数组用来运行时接受用户输入的参数;因为字符串在Java中是具有通用普遍性的,所以使用字符串是最优选择;数组的话,因为我们的参数不止一个,所以数组肯定是合适的;
不过自动JDK1.5引入动态参数后, String[]
数组也可以使用 String... args
来实现:
public static void main(String... args)
除了上面JVM规定的这个main方法比较特殊外,其他的main方法与普通的静态方法是没有什么不同的。
1. main方法能重载么?
这个是可以的,比如说我们给它重载一个方法:
public class Main { public static void main(String args) { System.out.println("hello world:" + args); } public static void main(String[] args) { main("test"); } }
编译运行,很显然没啥问题,除了JVM规定的作为应用程序入口的main方法之外,其他的main方法都是比较普通的方法。
2. main方法能被其他方法调用么?
public class Main { private static int times = 3; public static void main2(String[] args) { times--; main(args); } public static void main(String[] args) { System.out.println("main方法执行:" + times); if (times <= 0) { System.exit(0); } main2(args); } }
运行一下代码,可以发现代码能正常执行:
main方法执行:3 main方法执行:2 main方法执行:1 main方法执行:0
所以说即使是作为应用程序入口的main方法,也是可以被其他方法调用的,但要注意程序的关闭方式,别陷入死循环了。
3. main方法可以继承么?
我们以前了解过,当类继承时,子类可以继承父类的方法和变量,那么当父类定义了main方法,而子类没有main方法时,能继承父类的main方法,从而正常的运行程序么?
public class Main { public static void main(String[] args) { System.out.println("hello world"); } }
定义子类:
public class Main2 extends Main { }
这时候我们运行子类Main2,可以发现,同样打印了 hello world
,这说明main方法也是可以继承的。那么还有一种隐藏的情况也很显然了,子类定义自己的main方法,隐藏掉父类中的实现,那么这也是可以的。
public class Main2 extends Main { public static void main(String[] args) { System.out.println("hello world Main2"); } }
这时候就会打印子类自己的内容了: hello world Main2
。
这么来看,除了main方法作为应用程序的入口比较特殊外,其他情况下与正常的静态方法是没什么区别的。
本文主要参考自《细说Java》这本书。
以上所述就是小编给大家介绍的《Java 解惑系列(六):main 方法可以重载或者继承么》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- [短文速读] 重载有暗坑,重载重写你真的了解么
- 答疑解惑之nginx
- C# 空合并操作符(??)不可重载?其实有黑科技可以间接重载!
- 移动端H5解惑-页面适配(二)
- 移动端H5解惑-概念术语(一)
- 解惑3:时间频度,算法时间复杂度
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Paradigms of Artificial Intelligence Programming
Peter Norvig / Morgan Kaufmann / 1991-10-01 / USD 77.95
Paradigms of AI Programming is the first text to teach advanced Common Lisp techniques in the context of building major AI systems. By reconstructing authentic, complex AI programs using state-of-the-......一起来看看 《Paradigms of Artificial Intelligence Programming》 这本书的介绍吧!