概述

操作符
操作符接受一个或多个参数,并生成一个新值. 换句话说操作符作用于操作数,生成一个新值.有些操作符会改变操作数自身.
这种效应我们叫做side effect.

赋值
赋值操作符”=”的意思是,取右值赋值给左值.

右值可以是任意的常数,变量或者表达式(只要它能生成一个值). 但是左值必须是一个明确的已命名的变量. 也就是说必须有物理空间可以存储右值.

赋值也就是值传递,无论任何数据类型都遵循这一规则,都是取右值复制给左值. 但是对于不同的数据类型,赋值会有两种神奇的效果:

  • 对基本数据类型的赋值:

    • 基本数据类型的赋值直接赋的是”值”,就是直接把一个地方的内容复制到了另外一个地方
    • 对右值而言,没有任何改变和影响
  • 对于引用类型的赋值:
    • 引用类型的赋值实际赋的是对象的”引用”,赋值完成后,左值和右值都是同一个对象的引用.
    • 对于之后的两个变量来说,实际指向了同一个对象所以都可以对该对象进行操作.

String类型是一种比较奇葩的类型. String s1="aaa";首先String类型是不可变的类型. 比如这么一条语句,执行过程是先在常量池中开辟一块内存区域,存入”aaa” 然后将s1指向这块常量池中的这个区域.
所以对于下面这段代码,最后s1和s2分别会打印什么呢?

String s1="aaa";
String s2=s1;
s2="bbb";

s1是aaa,s2是bbb. 基础原则就是String类型是不可变的. 赋值过程很奇葩,就像上面说的一样.

关系操作符和逻辑操作符

关系操作符和逻辑操作符都会生成一个boolean值. 但是java中的布尔类型就是布尔类型,底层咋实现的我不知道,与C/C++中非0则true的实现不一样.

关系操作符中的等于==和不等于!=
在java中==操作符对于基本数据类型而言比较的是值,对于引用数据类型而言,比较的是”引用”.

    @Test
public void equalTest(){
Integer i1= new Integer(47);
Integer i2 = new Integer(47);
System.out.println(i1==i2);//false
System.out.println(i1.equals(i2));//true MyInteger myI1= new MyInteger(47);
MyInteger myI2 = new MyInteger(47); System.out.println(myI1==myI2);//false
System.out.println(myI1.equals(myI2));//false
}

上面这段代码就很清楚了,对于引用类型而言,i1和i2虽然都是Integer并且值为47. 但是其所指向的引用是不一样的. 所以==返回false. 但是euqals方法却返回true.因为Integer类型重写了queals方法. 像下面这个我自己创建了一个类,没有重写equals方法,那么equals方法默认行为还是比较引用.

什么事儿都逃不过一个理字, 基础数据类型的值是直接存放在栈上的,首先它没有引用.
另外即使java中所谓的引用就是C/C++中的指针,甚至是内存地址(当然它不是),每个变量存放的地址是不一样的,那比较它是没有任何意义.
对于”类”类型. 比较其”值”是没有意义的. 堆中不同的两个内存区域,即使存放的内容一毛一样,那也还是两块内存区域. 再者说,对于”类”类型(暂且这样叫吧,我也不知道它该叫啥,精神领会),绝大部分是用户自己定义的,java编译器不是神仙,不可能知道你定义的”类”类型里到底是个啥,它也揣摩不透你的比较逻辑.所以,所有类的祖宗Object类中给出了一个可以让你重写的equals方法. 给了你足够的自由.

逻辑操作符
逻辑操作符就那仨,与或非. 由于java布尔类型的特殊实现, 逻辑操作符无法作用于布尔类型之外的任何数据类型.
如果是在应该使用String值的地方使用了布尔类型,那么布尔类型会转成适当的String类型.

关于逻辑操作符,有个乱路机制. 也就是说一旦可以明确无误的缺点一个表达式的值,就不会再计算后面的部分了.

public class ShortCircuit {
public static boolean fun1(int val){
System.out.println("fun1("+val+")");
System.out.println("result:" + (val>1));
return val>1;
} public static boolean fun2(int val){
System.out.println("fun2("+val+")");
System.out.println("result:" + (val>4));
return val>4;
} public static boolean fun3(int val){
System.out.println("fun3("+val+")");
System.out.println("result:" + (val>5));
return val>5;
}
} @Test
public void logicalTest(){
int i =3;
boolean b = ShortCircuit.fun1(i)&&ShortCircuit.fun2(i)&&ShortCircuit.fun3(i);
System.out.println(b);
}
//output:
/*
fun1(3)
result:true
fun2(3)
result:false
false
*/

上面这例子可以看到,计算到fun2的时候,就可以确定这个逻辑表达式是false了. 所以就不会再往下计算了.

这让我想起来一件事儿,高中的时候,当我一本正经的在听老师讲题的时候. 同桌哥们在鼓捣其他事情. 我提醒他好好听讲,他问我,讲这题你会不.我说会呀. 他说,既然你会了干嘛还听它呢. 想想很有道理,于是打瞌睡去了…
当已经能明确确定这个表达式的值的时候,还往下计算,除了浪费资源之外还有什么用呢.

位操作符

位操作符按照剧本应该不会出现在java中,这种运算跟java屏蔽底层细节的画风严重不符,我也不明白它在java中有什么作用. 但是据说java当年是为了嵌入电视机机顶盒开发的,所以这种面向底层的操作还是被保留下来了.

移位操作符

  • 左移<<,低位补0.
  • 有符号右移>>,有符号的意思就是使用符号扩展,如果符号为正,则高位插入0 如果符号为负,则高位插入1;
  • 无符号右移>>>,无论符号正负,高位都插入0

对于char,byte和short类型,在移位操作前都会被转换成int类型.

原码,反码,补码
整数在计算机中的存储采用反码的形式.为什么采用反码呢,因为在使用反码的时候,计算逻辑是最简单的(因为不用区分符号位),而且不会出现0的两种编码形式.

原码就是符号位+真值. 整数符号位是0 负数符号位是1.
反码:正数的反码是其自身. 负数的反码是符号位不变,其他位取反
补码:正数的补码是其自身,负数的补码是符号位不变,其他位取反然后加1.

http://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html 更详细的参见这个.

类型转换

java中向上转型不需要特殊声明. 向下转型需要显式声明.
向下转型的时候,可能发生截尾. 如果需要舍入,则需要使用java.lang.Math下的round()方法.

关于类型转换还有两点:

  • 基本数据类型在和String一起拼接的时候,会调用toString方法,将其转换成String类型.
  • 不同的数字类型一起运算的时候,表达式中最大的数据类型决定了最终运算结果的数据类型.

java中没有sizeof()操作符. 因为这玩意儿不需要sizeof()… 下层是jvm,平台移植的问题由jvm来处理,不需要程序员去考虑这些事情.

TIJ读书笔记01-操作符的更多相关文章

  1. TIJ读书笔记02-控制执行流程

      TIJ读书笔记02-控制执行流程 TIJ读书笔记02-控制执行流程 if-else 迭代 无条件分支 switch语句 所有条件语句都是以条件表达式的真假来决定执行路径,也就是通过布尔测试结果来决 ...

  2. 《The Linux Command Line》 读书笔记01 基本命令介绍

    <The Linux Command Line> 读书笔记01 基本命令介绍 1. What is the Shell? The Shell is a program that takes ...

  3. TIJ读书笔记08-数组的初始化和可变长参数形参

    TIJ读书笔记08-数组的初始化和可变参数形参 数组 数组的声明 数组的初始化和赋值 可变参数列表 数组 相同类型的,用一个标识符名称封装到一起的一个对象序列或者基本数据类型序列叫数组.(多么严谨的概 ...

  4. TIJ读书笔记06-终结清理和垃圾回收

    TIJ读书笔记06-终结清理和垃圾回收 finalize()方法 垃圾回收器如何工作 java的垃圾回收是由jvm来控制的.所以需要java程序员参与的部分不是很多. 但是在这里需要明白一点,java ...

  5. TIJ读书笔记05-this关键字

    TIJ读书笔记05-this关键字 概述 this的用法 static方法 概述 两个对象同时调用一个方法,那么jvm怎么知道是哪个方法调用的呢. 我们在书写的时候会写成a.fun(1) 或者b.fu ...

  6. TIJ读书笔记04-方法重载

    TIJ读书笔记04-方法重载 为什么会有方法重载 方法签名 如何区分重载 关于基本类型的重载 为什么会有方法重载 OOP的编程方式就是让程序的逻辑更加接近现实世界的逻辑. 而在现实世界中,自然语言本身 ...

  7. TIJ读书笔记03-初始化和构造器

      TIJ读书笔记03-初始化和构造器 初始化和清理是涉及安全的两个问题,如果对象不能正确的初始化会引起很多错误,比如空指针异常等,如果不能恰当及时的清理,会占用过多资源. 构造器在创建一个类的实例的 ...

  8. YDKJ 读书笔记 01 Function vs. Block Scope

    Introduction 本系列文章为You Don't Know JS的读书笔记. 书籍地址:https://github.com/getify/You-Dont-Know-JS Scope Fro ...

  9. 硬盘和显卡的访问与控制(一)——《x86汇编语言:从实模式到保护模式》读书笔记01

    本文是<x86汇编语言:从实模式到保护模式>(电子工业出版社)的读书实验笔记. 这篇文章我们先不分析代码,而是说一下在Bochs环境下如何看到实验结果. 需要的源码文件 第一个文件是加载程 ...

随机推荐

  1. mybatis执行多条sql语句

    1,mybatis执行多条sql语句,有以下几种思路, a,存储过程 b,修改jdbc的参数,允许执行多条语句,如下所示: sqlserver可以直接使用begin,end来执行多条语句, mysql ...

  2. 【转】 详细介绍windows下使用python pylot进行网站压力测试

    windows下使用python进行网站压力测试,有两个必不可少的程序需要安装,一个是python,另一个是pylot.python是一个安装软件,用来运行python程序,而pylot则是pytho ...

  3. sqoop 从oracle导数据到hive中,date型数据时分秒截断问题

    oracle数据库中Date类型倒入到hive中出现时分秒截断问题解决方案 1.问题描述: 用sqoop将oracle数据表倒入到hive中,oracle中Date型数据会出现时分秒截断问题,只保留了 ...

  4. ASP.NET动态网站制作(24)-- ADO.NET(3)

    前言:ADO.NET的第三节课.今天主要讲SQL Helper. 内容: 1.DataReader和DataSet的区别: (1)DataReader是一行一行地读,且只能向前读:DataSet是一次 ...

  5. jquery中end()方法的解释

    来源:http://www.jquery001.com/jquery-end-method.html 对于end()方法,jQuery文档是这样解释的:jQuery回到最近的一个"破坏性&q ...

  6. 【转】Visual studio 快捷键大全

    原文:http://book.douban.com/review/4871157/ 可同时参考:http://www.cnblogs.com/TankXiao/p/3164995.html 还记得刚工 ...

  7. Laragon集成开发环境+配置Xdebug+postman运行Xdebug

    [ Laravel 5.5 文档 ] 快速入门 —— 使用 Laragon 在 Windows 中搭建 Laravel 开发环境:http://laravelacademy.org/post/7754 ...

  8. D - Find a way

    D - Find a way Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Desc ...

  9. linux linux 互传文件 win 不通过 ftp sftp 往linux 传文件(文件夹)

    linux 传入 传出文件 swp  port  22 怎样通过swp通过docker 容器向外传文件 通过scp Linux互传文件,需要知道文件源 file source 所在系统的ip wuse ...

  10. javascript基础(整理自廖雪峰)

    不要使用==比较,始终坚持使用===比较false == 0; //返回true. 这种情况, 它会自动转换数据类型再比较false === 0; //返回false. 建议用这种方式 NaN === ...