一些很容易遗忘的琐碎知识点,记录一下。
一、System.out其实是一个static方法,和main一样,所以可以不必new就直接调用。
System.getProperties.list(System.out)该语句System.getProperties是获取系统属性的一个东西,加上参数之后可以获得特定属性,如:System.getProperties(“user.name")或者java.library.path等;list是重定向,可以到某个文件,当然也可以到控制台。
二、
byte b = -1; print(Integer.toBinaryString(b)); print(Integer.toBinaryString(b>>>10)) b >>> = 10; print(Integer.toBinaryString(b));
结果:32个1(也就是-1),22个1,,32个1
原因:Integer.toBinaryString会把byte(8位),当然也包括char,short(两者都是16位)转换为int(32位),而在进行移位操作时,char,short,byte都会转换为int类型,然后进行截取,由于最后又赋值给b,所以22位再次被截取末尾若干位(跟b类型有关),然后打印的时候再次被Integer.toBinaryString转换回去,所以第三个结果是32个1;而第二个没有进行赋值操作,因此始终保持为int,结果是22个1。
三、接上面所讲,char,byte,short这种位数比int小的,进行基本运算(包括移位,与,或,取反等)时会先转换为int,如果不进行显示转换是不会自动转换为原来类型的。 另外,由于每种类型所占字节数在不同平台上都是相同的,因此java没有类似的sizeof这个函数。
四、java对于goto标签的处理:java没有goto(虽然它是保留字),但是却有标签,标签是为continue和break两个准备的。标签是字符串后面加上:
outer: for{ inner: for{ break; break inner; break outer; } }
其中break和break inner是同样作用,但是break outer却可以直接跳出第二层循环。需要注意的是,标签和for或while循环之间不要加任何语句,这样才能清晰明了。
五、垃圾回收机制:这部分内容过于庞大,因此直接拉出引用:http://hi.baidu.com/sunshinesky/item/f779f6c23fccd362f7c95dcb
六、初始化问题:
临时变量如果不进行初始化,会报错;而类成员变量(若为基础类型)则会存在默认值(false,0,null等);初始化顺序为,static(只在new的时候初始化一次),定义时候的直接赋值(如private int i = 1),构造器。初始化还有一种方式
static{ mug1 = new Mug(); }
前面static修饰也可以不要,存在的时候它只执行一次,优先级最高;不存在的时候它在每一次new时都执行,优先级第二(即比static低,比构造器高)。
七、java领域的JIT:
太长,参看wiki百科吧。简略说是java首先将源代码翻译成字节码,然后在jre上面解释执行,但速度太慢。所以会根据统计结果,将经常执行的部分编译成字节码。实际上是编译与解释共存的一个体系。
八、可变参数列表:实际上传入的就是一个数组,只是java帮助我们实现了,因此可以写成void f(String ... args)这种形式。由于可变参数个数包括0,因此在重载的过程中可能出现问题,即如果还存在void f(Integer... args)的话,f()的调用会让编译器不知何去何从。解决方案是尽量少用这个,或者另外加一个标示位来分辨是哪一个函数调用,或者在各个重载函数中,只有某一个使用可变参数。
九、enum其实可以看做类,两个常用函数,private enum s{},s.value()和s.original(),这个original和C的没什么差别,枚举的各个变量对应的分别就是1,2.3.4...
十、若某个类没有指定所在包,那么它们统一默认属于java工程的默认包,所以这些文件是属于同一个包内的;一个类可以加public或者不加,后者默认是包访问权限,一般用于该类只为包内其他类提供服务,private和protected对于类来说无意义;类中的方法;通过把构造器设定为private,可以令该类无法被new出来。注意:如果不显示定义构造器为private,那么它一定继承了一个public的构造器,是达不到不准实例化的目的的。
class Soup1{ private Soup1(){} public static Soup1 makeSoup(){ return new Soup1(); } } class Soup1{ private Soup1(){} private static Soup2 s2= new Soup2(); public static Soup1 makeSoup(){ return new s2; } }
这样就可以达到效果了。两种方式其实都有着特定的应用场景的:
1.在某些需要统计到底实例化了多少Soup1的场合下可以应用这种方式。当然也可以是别的操作,关于Soup1的,交给Soup1自然会更好。
2.这就是传说中的单例的设计模式的实现方式了,其实也可以直接把类定义为static,但是这种方式更优雅。另外,这本书读完,要读下一本:《Thinking in patterns(with java)》
十一、接口:接口方法是public的,接口域是public static final的。因此在有enum类型之前,可以用接口的域来模仿实现枚举;在接口这章,初识的设计模式有:策略模式、单例模式、工厂模式和适配模式。其中适配模式较为生疏,它适应于有一个外部类Y,已经无法修改,但是你的方法需要一个类是X类型的,因此在这里你可以new一个类AdaptedY类implements X,之后可以通过extends Y,也可以把Y做一个成员变量来和Y建立联系。简单说,就是把一个已有的与需要的接口无关联的类,与需要的接口关联起来的过程。
第二点是在接口A内定义子接口X为private类型的意义:是需要用到这样的类,但不想它可以向上转型为X。因为X在A内是private的,因此在接口外所有跟A.X有关的东西都将被是不可用的,包括在A内定义一个返回值为A.X的方法,在接口外调用会报错,因为类型是隐藏的。因此解决方法是在A内定义接收A.X类型参数的方法receiveX(A.X x),然后可以这样调用,A.receiveX(a.getX())——具体参见《thingking in java》第九章倒数第二个例子。