TIJ读书笔记01-操作符
概述
操作符
操作符接受一个或多个参数,并生成一个新值. 换句话说操作符作用于操作数,生成一个新值.有些操作符会改变操作数自身.
这种效应我们叫做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-操作符的更多相关文章
- TIJ读书笔记02-控制执行流程
TIJ读书笔记02-控制执行流程 TIJ读书笔记02-控制执行流程 if-else 迭代 无条件分支 switch语句 所有条件语句都是以条件表达式的真假来决定执行路径,也就是通过布尔测试结果来决 ...
- 《The Linux Command Line》 读书笔记01 基本命令介绍
<The Linux Command Line> 读书笔记01 基本命令介绍 1. What is the Shell? The Shell is a program that takes ...
- TIJ读书笔记08-数组的初始化和可变长参数形参
TIJ读书笔记08-数组的初始化和可变参数形参 数组 数组的声明 数组的初始化和赋值 可变参数列表 数组 相同类型的,用一个标识符名称封装到一起的一个对象序列或者基本数据类型序列叫数组.(多么严谨的概 ...
- TIJ读书笔记06-终结清理和垃圾回收
TIJ读书笔记06-终结清理和垃圾回收 finalize()方法 垃圾回收器如何工作 java的垃圾回收是由jvm来控制的.所以需要java程序员参与的部分不是很多. 但是在这里需要明白一点,java ...
- TIJ读书笔记05-this关键字
TIJ读书笔记05-this关键字 概述 this的用法 static方法 概述 两个对象同时调用一个方法,那么jvm怎么知道是哪个方法调用的呢. 我们在书写的时候会写成a.fun(1) 或者b.fu ...
- TIJ读书笔记04-方法重载
TIJ读书笔记04-方法重载 为什么会有方法重载 方法签名 如何区分重载 关于基本类型的重载 为什么会有方法重载 OOP的编程方式就是让程序的逻辑更加接近现实世界的逻辑. 而在现实世界中,自然语言本身 ...
- TIJ读书笔记03-初始化和构造器
TIJ读书笔记03-初始化和构造器 初始化和清理是涉及安全的两个问题,如果对象不能正确的初始化会引起很多错误,比如空指针异常等,如果不能恰当及时的清理,会占用过多资源. 构造器在创建一个类的实例的 ...
- YDKJ 读书笔记 01 Function vs. Block Scope
Introduction 本系列文章为You Don't Know JS的读书笔记. 书籍地址:https://github.com/getify/You-Dont-Know-JS Scope Fro ...
- 硬盘和显卡的访问与控制(一)——《x86汇编语言:从实模式到保护模式》读书笔记01
本文是<x86汇编语言:从实模式到保护模式>(电子工业出版社)的读书实验笔记. 这篇文章我们先不分析代码,而是说一下在Bochs环境下如何看到实验结果. 需要的源码文件 第一个文件是加载程 ...
随机推荐
- K - Large Division 判断a是否是b的倍数。 a (-10^200 ≤ a ≤ 10^200) and b (|b| > 0, b fits into a 32 bit signed integer). 思路:取余;
/** 题目:K - Large Division 链接:https://vjudge.net/contest/154246#problem/K 题意:判断a是否是b的倍数. a (-10^200 ≤ ...
- 什么时候触发MinorGC?什么时候触发FullGC?
触发MinorGC(Young GC) 虚拟机在进行minorGC之前会判断老年代最大的可用连续空间是否大于新生代的所有对象总空间 1.如果大于的话,直接执行minorGC 2.如果小于,判断是否开启 ...
- Android 混淆完全解析
1.http://blog.csdn.net/jddkdd2/article/details/8858909
- 利用JNDI的命名与服务功能来满足企业级API对命名与服务的访问
包含了大量的命名和目录服务,使用通用接口来访问不同种类的服务: 可以同时连接到多个命名或目录服务上: 建立起逻辑关联,允许把名称同Java对象或资源关联起来,而不必知道对象或资源的物理ID. JNDI ...
- Pig系统分析(8)-Pig可扩展性
本文是Pig系统分析系列中的最后一篇了,主要讨论怎样扩展Pig功能.不仅介绍Pig本身提供的UDFs扩展机制,还从架构上探讨Pig扩展可能性. 补充说明:前些天同事发现twitter推动的Pig On ...
- ROS导航之地图costmap_2d与bresenham算法
读者可以参读http://wiki.ros.org/costmap_2d costmap_2d: 无论是激光雷达还是如kinect 或xtion pro深度相机作为传感器跑出的2D或3D SLAM ...
- 根据funID,personID获取最新规划包项目相关信息
1.定义:根据funID,personID获取最新规划包项目相关信息(code projecttype(阶段) Pname(code+name) projectID) 项目表tbl_cfg_Proje ...
- C# 如何判断系统是32位还是64位
摘自:http://www.cnblogs.com/tom-tong/archive/2012/03/12/2392173.html public static int GetOSBit() { tr ...
- HTML学习笔记——常用元素及其属性(二)
一.HTML表单 -- form标签 -- 与浏览者交互 1.form 标签 -- 代表HTML表单 form标签是成对出现的,以<form>开始,以</form>结束 属性. ...
- tomcat开启远程调试
tomcat开启远程调试模式: 需要在启动脚本中的 JAVA_OPTS='-server -Xms1024m -Xmx1024m -Xmn384m -Xss256k -XX:PermSize=128m ...