java编程思想学习日志——操作符

在最底层,Java中的数据是通过使用操作符来操作的。

  • 操作符

操作符作用于操作数,生成一个新值。另外,有些操作符可能会改变操作数自身的值,这被称为“副作用”。那些能改变其操作数的操作符,最普遍的用途就是用来产生副作用;但是要记住,使用此类操作符生成的值,与使用没有副作用的操作符生成的值,没有什么区别。
几乎所有的操作符都只能操作“基本类型”。例外的操作符是“=”、“==”和“!=”,这些操作符能操作所有对象。除此之外,String类支持“+”和“+=”。

当一个表达式中存在多个操作符时,操作符的优先级就决定了各部分的计算顺序。Java对计算顺序做了特别的规定。其中,最简单的规则就是先乘除后加减。程序员经常会忘记其他优先级规则,所以应该用括号明确规定计算顺序

  • 赋值

赋值使用操作符“=”。他的意思是“取右边的值,把它复制给左边”。右值可以是任何常数、变量或者表达式。单左值必须是一个明确的、已命名的变量。也就是说,必须有一个物理空间可以存储等号右边的值

对基本类型的赋值很简单,是存储了实际的数值,而不是指向一个对象的引用,是直接将一个对象的内容复制到了另一个地方。但是在为对象赋值时,我们操作的是对对象的引用。倘若“将一个对象赋值给另一个对象”,实际是将“引用”从一个地方复制到另一个地方。这意味着假若对对象使用c=d,那么c和d都指向原本只有d指向的那个对象,因为c被赋予了d的值,所以Java会认为c原来的对象不会被使用了,而被垃圾回收器回收。这种特殊的现象通常被称作“别名现象”,是Java操作对象的一种基本方式。

import static net.mindview.util.Print.*;

class Tank{
    int level;
}

public class Assignment{
    public static void main(String[] args){
        Tank t1 = new Tank();
        Tank t2 = new Tank();
        t1.level = 9;
        t2.level = 46;
        print(t1.level);  // 9
        print(t2.level);  // 46
        t1 = t2;
        print(t1.level);  // 46
        print(t2.level);  // 46
        t1.level = 11;
        print(t1.level);  // 11
        print(t2.level);  // 11
    }
}
  • 算术操作符

Java的基本算术操作符与其他大多数程序设计语言是相通的,整数除法会直接去掉结果的小数位。要生成数字,程序首先会创建一个Random类的对象,通过它程序可生成许多不同类型的随机数字,只需调用nextInt()、nextFloat()等方法即可。传递给nextInt()的参数设置了所产生的随机数上限,而其下限为零,为防止产生0,一般我们在后面进行加1操作。
一元减号(-)用于转变数据的符号,而一元加号只是为了与一元减号相对应,它唯一的作用是将较小类型的操作数提升为int。

  • 自动递增和递减

++和–有“前缀式”和“后缀式”两种使用方式,前缀先运算后生成值,后缀先生成值再执行运算。它们是熟了那些涉及赋值的操作符以外,唯一具有“副作用”的操作符。他们会改变操作数,而不仅仅是使用自己的值。

import static net.mindview.util.Print.*;

public class AutoInc {
    public static voin main(String[] args){
        int i = 1;
        print("++i:" + ++i);  // ++i:2
        print("i++:" + i++);  // i++:2
        print("i:" + i);      // i:3
    }
}
  • 关系操作符

关系操作符==和!=适用于所有对象,但是对不同的对象其比较的内容性质不同。只有基本类型才会直接比较其内容,其余对象比较的是对象的引用。所以相比较对象内容是否一致时,需要使用equals()方法。但是在使用equals()时要注意所比较的对象是否覆盖了equals()方法
大多数Java类库都实现了equals()方法,以便用来比较对象的内容,而非比较对象的应用。

class Value{
    int i;
}
public class EqualsMethod {

    public static void main(String[] args){
        Integer n1 = new Integer(12);
        Integer n2 = new Integer(12);
        System.out.println(n1==n2);

        int n3 = new Integer(12);
        int n4 = new Integer(12);
        System.out.println(n3==n4);

        Value v1 = new Value();
        Value v2 = new Value();
        v1.i = v2.i = 100;
        System.out.println(v1==v2);
        System.out.println(v1.equals(v2));

    }

}
/*
    false
    true
    false
    false
*/
  • 逻辑操作符

逻辑操作符与(&&)、或(||)、非(!)能根据参数的逻辑关系,生成一个布尔值(true或false)。它们的操作只可应用于布尔值。与C和C++不同的是,不可将一个非布尔值在逻辑表达式中使用。如果在应该使用String值的地方使用了布尔值,布尔值会自动转换成适当的文本形式:

import static net.mindview.util.Print.*;

public class Bool {

    public static void main(String[] args){
        print("istrue".equals("is"+true));
    }

}//和"istrue"作比较的"is"+true,后面的true是布尔值,但是这里直接用作文本

当使用逻辑操作符时,我们会遇到一种“短路”现象。即一旦能够明确无误地确定整个表达式的值,就不再计算表达式余下部分了。因此,整个逻辑表达式靠后的部分有可能不会被运算。如果所有的逻辑表达式都有一部分不必计算,那将获得潜在的性能提升。

  • 直接常量

一般说来,如果在程序里使用了“直接常量”编译器可以准确地知道要生成什么样的类型,但有时候却是模棱两可的。如果发生这种情况,必须对编译器加以适当的“指导”,用与直接量相关的某些字符来额外增加一些信息。
直接常量后面的后缀字符标志了它的类型。L代表long,F代表float,D代表double;都可以使用小写,但是L的小写容易与数字1混淆,所以不推荐

十六进制数适用于所有整数数据类型,以前缀0x(或0X),后面跟随0-9或小写(或大写)a-f来表示。如果试图将一个变量初始化成超出自身表达范围的值,编译器都会向我们报告一条错误信息。如果超出范围,编译器会将值自动转换成int型,并告诉而我们需要对这次赋值进行“窄化转型”。这样我们就可清楚的知道自己的操作是否越界。
八进制数由前缀0以及后续的0-7数字来表示。

Java采用了一种很不直观的计数法来表示指数。在科学与工程领域,“e”代表自然对数的基数,约等于2.718。但是Java使用了源于FORTRAN语言的C、C++的语言习惯,在计数时e代表“10的幂次”
编译器通常会将指数作为双精度数(double)处理,所以在指数计数时要时常记得转换对象类型:

float f = 1e-43f;//这里不尾随f则会报错,提示必须将double转换成float
  • 按位操作符

按位操作符用来操作整数基本数据类型中的单个“比特”(bit),即二进制位。按位操作符会对两个参数中对应的位执行布尔代数运算,并最终产生一个结果。按位操作符来源于C语言面向底层的操作,在这种操作中经常需要直接操作硬件,设置硬件寄存器内的二进制位。

我们将布尔类型作为一种单比特值对待,所以它多少有些独特。他不能执行按位“非”操作(避免与逻辑NOT混淆);具有与逻辑操作符相同的效果,但是不会中途“短路”;在移位表达式中,不能使用布尔运算。

  • 移位操作符

移位操作符操作的运算对象也是二进制的“位”。移位操作符只可用来处理整数类型(基本类型的一种)。Java中增加了一种“无符号”右移位操作符(>>>),它使用“零扩展”:无论正负,都在高位插入0,这一操作符是C和C++所没有的。

如果对char、byte或者short类型的数值进行移位处理,那么在移位进行之前,他们会被转换为int类型,并且得到的结果也是一个int类型的值。只有数值右端的低五位才有用。这样可防止我们移位超过int型值所具有的位数(long为低6位)。

“移位”与“等号”组合使用,操作符左边的值会移动到右边的值指定的位数,再将得到的结果赋给左边的变量。但如果对byte或short值进行这样的移位运算,得到的可能不是正确的结果。他们会先被转换成int类型,再进行右移操作,然后被截断,赋值给原来的类型,在这种情况下可能得到-1的结果。
数字的二进制表示形式称为“有符号的二进制补码”。

  • 三元操作符if-else

三元操作符也称为条件操作符,具有三个操作数

import static net.mindview.util.Print.*;

public class TernaryIfElse {
    static int ternary(int i){
        return i<10 ? i*100 : i*10;//三元操作符
    }
    static int standardIfElse{
        if(i<10)
            return i*100;
        else
            return i*10;
    }
    public static void main(String[] args){
        print(ternary(9));
        print(ternary(10));
        print(standardIfElse(9));
        print(standardIfElse(10));
    }
}

前者的代码更加紧凑,但是后者的代码更容易理解,而且不需要太多的录入。所以在选择使用三元操作符时,要仔细考虑。

  • 类型转换操作符

类型转换(cast)的原意是“模型铸造”。在适当的时候,Java会将一种数据类型自动转换成另一种。类型转换运算允许我们显式的进行这种类型的转换,或者在不能自动进行转换的时候强制进行类型转换。

想要执行类型转换,需要将希望得到的数据类型置于括号内,放在要进行类型转换的值的左边。既可对数值进行类型,亦可对变量进行类型转换。在Java中,类型转换是一种比较安全的操作。但是执行窄化转换时可能面临数据丢失的危险。

Java允许我们把任何基本数据类型转换成别的基本数据类型(布尔类型除外)。“类”数据类型不允许进行类型转换。为了将一种类转换成另一种,必须采用特殊的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值