程序一: i++
i = i++; //等效于如下三行
int temp = i ; //temp是指其保留值
i = i+1; //++的执行效果
i = temp; //i的最后赋值是由temp决定的 故而i依然为其本值(temp将i+1覆盖掉了)
小实例如下:
public static void main(String[] args)
{
Demo inc = new Demo();
int i = 0;
inc.fermin(i); //此处必须要用实例化后的对象来调用fermin()方法,因为fermin()方法非静态
i = i++; //此处的i的temp依旧是0,temp将1覆盖掉了
System.out.println(i);
}
private void fermin(int i) //此处的函数是一个void(无返回值)类型,i++虽然变成1,但并不返回
{
i++;
}
深度探究例子二:
public static void main(String[] args)//此程序是++运算符的完美体现
{
int i = 0;
i = i++ + ++i; //先执行i++(其值为1) 在执行++i(其值为1) 再要补增i++(自增是右边执行完毕后自增),所以结果为2
int j = 0;
j = ++j + j++ + j++ + j++; //先执行++j(其值为1) 在执行j++(其值为1) 再执行j++(仍是1,但是补加前一个j++,结果为2),
int k = 0; // 再执行最后一个j++(仍是2,补加上前面的(j++为2)结果为3) 1+1+2+3=7
k = k++ + k++ + k++ + ++k; //k++(其值为0),在执行k++(加上前一个为1),再执行k++(加上前一个为2)
int h = 0; //最后执行++k的时候,自增加1,前一个k++增1,结果为4 输出为0+1+2+4 = 7
h = ++h + ++h;
int p1 = 0,p2 = 0; //此处四个变量体现的是++放在变量的前后的不同效果即是 ++i 和 i++的区别
int q1 = 0,q2 = 0;
q1 = ++p1; //++放在变量前直接自增 p1为1 q1也为1
q2 = p2++; //++放在变量后的话如上语句执行所示,执行完毕后自增
System.out.println("i-->"+i);
System.out.println("j-->"+j);
System.out.println("k-->"+k);
System.out.println("h-->"+h);
System.out.println("p1-->"+p1);
System.out.println("p2-->"+p2);
System.out.println("q1-->"+q1);
System.out.println("q2-->"+q2);
}
程序运行结果如下;
i-->2
j-->7
k-->7
h-->3
p1-->1
p2-->1
q1-->1
q2-->0
程序二:初始化构造器解析
//程序创建了三个类,Root,Mid,Leaf,类中均有静态初始化块和普通初始化块,展现的目的就是观察实例化构造器,静态初始化块的执行先后,以便更好的理解程序
创建一个对象的时候,先为该对象的所有实例属性分配内存(该类已经被加载过了),然后对实例属性进行初始化:一下就是执行顺序的解释
package com.itheima;
public class Demo
{
public static void main(String[] args)
{
new Leaf();//匿名实例化对象,
new Leaf();//第二次实例化对象,Leaf类中在虚拟机中存在,有关静态的块也就是存在,无需对Leaf进行初始化
}
}
class Root
{
static
{
System.out.println("Root的静态初始化块"); //静态初始化块是属于类级别的,在类初始化的时候方才执行
}
{
System.out.println("Root的普通初始化块"); //初始化块是对构造器的补充,在构造器执行之前执行,也可使用初始化块来进行对象的初始化操作(固定的代码不接受参数)
}
public Root()
{
System.out.println("Root的无参构造器");
}
}
class Mid extends Root{
static
{
System.out.println("Mid的静态初始化块");
}
{
System.out.println("Mid的普通初始化块");
}
public Mid() //有时候会用到无参构造器,但很多时候会被覆盖,此时就必须显示写出构造器
{
System.out.println("Mid的无参构造器");
}
public Mid(String msg)
{
this(); //通过this 调用同一类中重载的构造器,要求必须显示写出无参构造器
System.out.println("Mid的带参数的构造器,其参数值为"+msg);
}
}
class Leaf extends Mid{//这里实现继承就是为了更好的体现隐藏在内的java.lang.Object,更能体现对象实例化的时候是其父类先实例化
static
{
System.out.println("Leaf的静态初始化块");
}
{
System.out.println("Leaf的普通初始化块");
}
public Leaf()
{
super("调用父类有一个参数的构造器"); //通过super 调用父类有一个参数(String类型)的构造器
System.out.println("执行leaf的构造器");
}
}
运行结果如下:
小程序三:
1.==比较时若是变量且都是基本类型的变量,即数值型(不一定要求数据类型严格相等) 则只要变量的值相等,就会返回true
引用变量必须指向同一个对象, (==不可比较类型上没有父子关系的两个对象)
2.equals方法是Object类提供的一个实例方法,所有引用变量都可以调用此方法来判断
3.其实String中已经重写了Object的equals()方法 就像数组中重写了Object的toString()方法一样
标准是:只要两个字符串所包含的字符串序列相等,通过equals比较将返回true
4.易混淆点: Object中的equals和String中的equals不一样
Object中的equals()方法实际中没有多大意义(只是比较的对象的地址)
int it = 63;
float it2 = 63.0f; //不加f默认是double
System.out.print("63和63.0f是否相等"+"-->"+(it==it2)); //true 数值类型的判定
char ch = 'a';
int ch2 = 97;
System.out.print("\na和97是否相等"+"-->"+(ch==ch2));//true 此处为一个比较特殊的实例,char类型在底层也是属于int类型范围
String str = new String("a为63");
String str2 = new String("a为63");
System.out.print("\nstr和str2是否相等"+"-->"+(str==str2)); //false 引用类型的判定,本人第一篇写过其内部引用不同
System.out.print( "\nstr和str2是否相等用equals判断"+"-->"+(str.equals(str2)));//true
由于instanceof的特殊性,即当前对象是后面类的实例或其子类时都将返回true
实际上使用重写equlas()方法判断两个对象的是否是同一个类的实例时是有问题的 成熟的equals()方法如下:
private String name;
private String idStr;
public boolean equals(Object obj)
{
if(this==obj)
{
return true;
}
}