日志标签:月经贴释疑

对象实例化的顺序

分类:java, 基础评论:6条作者:ticmy日期:2012-11-08

创建一个对象大概有以下几种方式: 1、通过new关键字,如new Object(); 2、通过某些反射类的newInstance方法,如Class#newInstance、Constructor#newInstance; 3、如果对象是Cloneable的,通过clone方法; 4、通过ObjectInputStream#readObject反序列化; 以上是通过java程序可以创建出对象的方式,jvm中还有一些隐式创建对象的地方,譬如: 1、启动一个类,main方法的参数String数组是隐式创建的,如果指定了一个或多个String对象,还要创建这些String对象; 2、读入一个class二进制数据的时候,创建一个与之对应的java.lang.Class类的对象; 3、在使用“+”进行字符串变量连接时,可能会创建StringBuffer/StringBuilder对象; 如此等等。 那么,在程序中通过new或newInstance创建对象(后面说创建对象均指这两种方式)的时候,构造方法、实例变量、父类构造方法、父类实例变量等的执行顺序是怎样的? 在创建对象的时候,首先会分配内存,此时所有实例变量均为默认值,然后做初始化实例变量、构造方法调用等操作。对于类变量,在创建对象之前,加载类的时候已经做掉了,这里为避免干扰,忽略掉。 先来一个例子: public class Init { public static v…

+=与=..+..的区别

分类:java, 基础评论:11条作者:ticmy日期:2012-09-28

在书本中,课堂上,关于a+=b大都说等价于a = a+b,其实不然,+=中包含着更多的东西。 在继续之前,来温故一点基础(为简单起见,只说整数)。 1、做基本运算(如+、-、*、/、、>>>、~、^等),当两个操作数的类型是byte,short,char,int之一的时候,结果的类型是int; 2、做整数基本运算时,当一个操作数是long,结果是long; 3、不加任何修饰的整数字面值默认就是int类型。 下面对上面的几点举例说明: short s1 = 1;//OK short s2 = s1 + 1;//ERROR 上面的第一句1整形字面值,它的类型是int,为什么可以直接赋值给short呢?因为字面值都是常量,编译器能很容易的检测出它到底在不在short所能表示的值的范围内。当写成short s1 = 32768的时候,编译就知道short容不下32768了,就会报错。 而对于第二句,s1是short类型,1是int类型,结果是int类型,自然不能自动赋值给short类型的s2了,因为有潜在的高位有效值被截断的风险。可能会有人想,上面s1已经赋值了一个字面值,对于下面的s2,编译器应该也可以计算出它的值啊。如果s1是final的,确实会这样,但s1是变量,编译器是无法预测它会不会在运行期改变的,即使它可能不会改变。 再来一个,计算一年有多少毫秒…

equals和==

分类:java, 基础评论:5条作者:ticmy日期:2012-07-10

很多不明真相的javaer喜欢纠结于此问题,特来解释一二。 先看代码 StringBuilder s1 = new StringBuilder(); StringBuilder s2 = new StringBuilder(); String s = "abc"; s1.append(s); s2.append(s); System.out.println("s1.equals(s2):\t\t" + (s1.equals(s2))); System.out.println("s1 == s2:\t\t" + (s1 == s2)); String s3 = s + "1"; String s4 = s + "1"; System.out.println("s3 == s4:\t\t" + (s3 == s4)); System.out.println("s3.equals(s4):\t\t" + (s3.equals(s4))); Object obj1 = new Object(); Object obj2 = new Object(); System.out.println("obj1.equals(obj2):\t" + (obj1.equals(obj2))); System.out.println("obj1 == obj2:\t\t" + (obj1 == obj2)); 执行结果如下 s1.equals(s2): false s1 == s2: false s3 == s4: false s3.equals(s4): true obj1.equals(obj2): false obj1 == obj2: false 有人说“==比较地址,equals比较内容”,从String的比较来看这是对的,但从上述StringBuilder来…

java中到底有没有指针

分类:java, 基础评论:4条作者:ticmy日期:2012-07-04

学过c/c++,然后学java的人往往心中有此纠结,java中到底有没有指针? 如果一定要在是或否里选择一个,OK,java中没有指针。 那么,java中的引用(reference)和c/c++中的指针(如无特别说明,后文指针均指c/c++中的指针)究竟有着什么样纠葛不清的关系呢? 在开始之前先说一下c/c++的引用,它跟java的引用完全不是一个东西,c/c++的引用是同一块内存的不同名字。而java的引用是指向一个对象,引用本身也占用了内存。 首先,列举一下能对指针进行的一些常见操作: 1、指向一个对象,如 Person *p = new Person….;int *iv = new int…. 2、对指针所指的对象进行操作:P->getAge();            (*p).getAge(); 3、获取存储在指针中的地址值。 4、将指针指向另外一个对象:Person *p1 = new Person…; p = p1;    但,不可以*p = p1这样来赋值。 5、删除new的空间,delete p1; 6、其它诸多操作 这么多已经足够了,接下来看看java引用能做什么操作。 a、指向一个对象,如Person p = new Person… b、调用对象的方法,p.getAge(); c、指向另外一个对象,Person p1 = new Person…; p = p1; OK,就这么多了。 对于a和1,他们的…

Integer与int解惑

分类:java, 基础评论:14条作者:ticmy日期:2012-06-06

jdk1.5引入了自动装箱(autoboxing)与自动拆箱(unboxing),这方便了集合类以及一些方法的调用,同时也使初学者对其感到非常之困惑。在此,我们来揭开其神秘的面纱。 首先,需要厘清一些概念: 1、Integer是一个类,用Integer声明一个变量其是一个对象类型(或者说引用类型);int是基本类型,用int声明的变量是非对象类型,即不能在其上调用方法。 2、“==”作用于对象上的时候,其比较的是对象的引用本身的值(或者说对象的地址更容易理解),而作用于基本类型的时候比较的就是基本类型的值。 接下来看一段代码: public class Test { public static void main(String[] args) { Integer i1 = 2; int i2 = 2; System.out.println(i1 == i2); } } 在这段代码中有两个令人困惑的问题,首先是将一个基本类型的值赋值给对象的引用,即Integer i1 =2;其次是拿一个对象类型和一个基本类型比较。按理说这两种做法肯定都是有问题的,在jdk1.4(若使用的jdk版本是1.5或之后的版本中,可以使用javac -source 1.4 Test.java来编译)上,确实如此,第一个问题在编译时会报“不兼容的类型”错误,第二个问题会报“运算符 == 不能应用于 java.lang.Integer…
经常看到一些论坛在谈java代码优化的时候讲到要将字符串连接操作”+”换成StringBuilder(或StringBuffer,后面为简单起见,只说StringBuilder)的append操作以提升性能,那么字符串连接使用StringBuilder#append来替代”+”真的会带来性能提升吗? 不忙回答,先看几个例子,代码如下: public class StringConcat { public static void main(String... args) { concat1(); concat2(); concat3(); } public static void concat1() { String s = "today is " + "a good day"; System.out.println(s); } public static void concat2() { int count = 2; String tmp = " on the desk"; String s2 = "there are " + count + " books " + tmp; System.out.println(s2); } public static void concat3() { String s3 = ""; for(int i=0; i<100; i++) { s3 = s3 + i; } System.out.println(s3); } } 接下来分别分析下这三个操作字符串的方法,通过javap命令反编译.class文件:javap -c StringConca…