1. 算数运算符

就是+、-、*、/、%、++、--这些,没什么好说的,稍微强调下自加,自减:

  • 前缀自增自减法(++i,--i): 先进行自增或者自减运算,再进行表达式运算。
  • 后缀自增自减法(i++,i--): 先进行表达式运算,再进行自增或者自减运算。
  • 结果的精度取操作数中精度高的那个。
  • char和byte类型数据运算结果的精度是int型数据的精度。
  • Math类里面提供了许多数学函数,如sqrt,pow,log,exp等,还有表示圆周率和e常量的近似值:PI,E。
  • 可移植性是Java语言的设计目标之一。无论在哪个虚拟机上运行,同一运算应该得到同样的结果。对于浮点数的运算结果,实现这样的可移植性是十分困难的。double类型使用64位存储一个double数值,但是有些处理器使用80位浮点寄存器。这些寄存器增加了中间过程的精度,可以使运算结果更精确,同时也可以避免产生指数溢出。但是,这个结果可能和始终在64位机器上运算的结果不一样,这是我们所不愿意看到的。Java虚拟机的最初规范是要求所有的中间计算必须截断。但是这样不仅可能导致溢出,还要耗费额外的时间。现在是默认允许中间计算采用扩展的精度,对使用关键字strictfp的方法,则必须使用严格的浮点计算来产生理想的结果。区别就是前者不会产生溢出,而后者则有可能。不过,对大多数程序来说,浮点溢出不属于大问题,关键字strictfp并不经常使用。

2. 逻辑运算符

就是与(&&)、或(||)、非(!),异或(^)。

短路逻辑运算符

使用与逻辑运算符时,若两个操作数都为true,则结果为true,但是当得到第一个操作为false时,其结果就必定是false,这时就不会再判断第二个操作。

举例:

public class Test{
public static void main(String[] args){
int a = 5;
boolean b = (a < 4) && (a++ < 10);
System.out.println("b= " + b);
System.out.println("a= " + a);
}
}

运行结果:

ps:或逻辑类似的,前一个为真就直接为真,像Python中的 and 和 or 的短路计算也是这样(参见Python2.7 - IMOOC - 4)。

3. 位运算符

位运算时先转换为二进制,再按位运算。

表格中的例子中,变量a的值为60(0011 1100),变量b的值为13(0000 1101):

  • 没有"<<<"运算符。
  • 1<<35与1<<3或8是等价的,long类型则是模64。
  • 通过运用2的幂次方的&运算可以屏蔽掉其它位,检测某一位是否为1:(n & 2 ^ n) / 2 ^ n(用移位符实现屏蔽显然更易理解)。
  • 可以用异或位运算进行加密:原文字符和约定数进行异或位运算得到密文,密文再和约定数进行异或位运算得到原文。
  • 位运算也可以操作字符数据,但运算结果是int型数据。
  • 位运算也可以操作逻辑型数据,规则类似,不同的是位运算符要计算完两边的操作数之后再给出运算的结果。下面的例子可以看出短路逻辑和位运算的不同
public class Test{
public static void main(String[] args){
int x;
int y = 10;
if(((x = 0) == 0) || (y = 20) == 20){
System.out.println("now y = " + y);
} int a;
int b = 10;
if(((a = 0) == 0) | (b = 20) == 20){
System.out.println("now b = " + b);
}
}
}

运行结果:

4. 赋值运算符

=、+=、-=之类,还可以<<=、&=这样。

5. 关系运算符

写在判断条件里的==、!=、>、<......

==和!=也适用于所有对象,可以比较对象的引用是否相同。

引用:Java 中一切都是对象,但操作的标识符实际是对象的一个引用。

例:

  String s;

在这里,创建的是引用,不是对象。创建引用后,一种安全的做法是对其进行初始化。

  String s = "abc";
String s = new String("abc");

通常采用new操作符生成一个新对象,然后将引用与该对象相关联。

来看下面的代码:

public class Test {
public static void main(String args[]){
Integer n1 = new Integer(2);
Integer n2 = new Integer(2);
System.out.println(n1 == n2);
System.out.println(n1 != n2);
}
}

在上面的代码中,输出的结果是什么呢,可能认为先是true,再是false,因为两个对象是相同的。尽管两个对象的内容相同,但它们的引用却不相同,==和!=比较的就是对象的引用,所以结果false,再是true,如下:

而想要比较对象的内容是否相同时,Java 提供了一个特殊的方法equals(),它不适用于基本类型,基本类型使用==和!=进行比较。

来看下面的代码:

public class Test {
public static void main(String args[]) {
Integer n1 = new Integer(2);
Integer n2 = new Integer(2);
System.out.println(n1.equals(n2));
}
}

上述的代码运行结果:

注:但是当自己创建了一个类时,情况又会相反,因为equals()默认比较引用,除非在自己的类中覆盖equal()方法,这些知识将在之后的章节进行详细讲解。

这都是什么鬼,稍微了解了一下java的对象和引用:

new是在内存中为对象开辟空间。具体来说,new是在内存的 (heap)上为对象开辟空间。这一空间中,保存有对象的数据和方法。对象连名都没有,没法直接访问它。我们只能通过对象引用来间接访问对象。对象引用(reference)并不是对象本身,而是类似于一个指向对象的指针,存在于内存的(stack)中。在Java中,引用起到了指针的作用,但我们不能直接修改指针的值,比如像C语言那样将指针值加1。我们只能通过引用执行对对象的操作。这样的设计避免了许多指针可能引起的错误。用等号赋值时,是将右侧new在堆中创建对象的地址赋予给对象引用。当我们将一个引用赋值给另一个引用时,我们实际上复制的是对象的地址。两个引用将指向同一对象。引用可以指向不同的对象,对象也可以被多个引用操纵。

栈的读取速度比堆快,但栈上存储的数据受到有效范围的限制。在C语言中,当一次函数调用结束时,相应的栈帧(stack frame)要删除,栈帧上存储的参量和自动变量就消失了。Java的栈也受到同样的限制,当一次方法调用结束,该方法存储在栈上的数据将清空。在 Java中,所有的(普通)对象都储存在堆上。因此,new关键字的完整含义是,在堆上创建对象。基本类型(primitive type)的对象,比如int, double,保存在栈上。当我们声明基本类型时,不需要new。一旦声明,Java将在栈上直接存储基本类型的数据。所以,基本类型的变量名表示的是数据本身,不是引用。

随着方法调用的结束,引用和基本类型变量会被清空。由于对象存活于堆,所以对象所占据的内存不会随着方法调用的结束而清空。进程空间可能很快被不断创建的对象占满。Java内建有垃圾回收(garbage collection)机制,用于清空不再使用的对象,以回收内存空间。垃圾回收的基本原则是,当存在引用指向某个对象时,那么该对象不会被回收; 当没有任何引用指向某个对象时,该对象被清空,它所占据的空间被回收。实际上这不确切。正确地说,它已成为垃圾回收机制的处理对象。至于什么时候真正被回收,那要看垃圾回收机制的心情了。由此看来,下面的语句应该不合法吧?至少是没用的吧?

  new Vehicle();

不对。它是合法的,而且可用的。譬如,如果我们仅仅为了打印而生成一个对象,就不需要用引用变量来系住它。最常见的就是打印字符串:

  System.out.println(“I am Java!”);

字符串对象“I am Java!”在打印后即被丢弃。有人把这种对象称之为临时对象

当我们分离了引用和对象的概念后,Java方法的参数传递机制实际上非常清晰: Java的参数传递为值传递。也就是说,当我们传递一个参数时,方法将获得该参数的一个拷贝。实际上,我们传递的参数,一个是基本类型的变量,另一个为对象的引用。基本类型变量的值传递,意味着变量本身被复制,并传递给Java方法。Java方法对变量的修改不会影响到原变量引用的值传递,意味着对象的地址被复制,并传递给Java方法。Java方法根据该引用的访问将会影响对象。但是,需要理解的是,不能改变引用,使其指向另外一个对象。

6. 条件运算符

唯一的一个三目运算符条件运算符?

语法形式:布尔表达式?表达式1 : 表达式2

运算过程:如果布尔表达式的值为true ,则返回 表达式1 的值,否则返回 表达式2 的值。

7. instanceof 运算符

该运算符用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)。

instanceof运算符使用格式如下:

  ( Object reference variable ) instanceof  (class/interface type)

如果运算符左侧变量所指的对象,是操作符右侧类或接口(class/interface)的一个对象,那么结果为真。

下面是一个例子:

String name = "James";
boolean result = name instanceof String; // 由于 name 是 String 类型,所以返回真

如果被比较的对象兼容于右侧类型,该运算符仍然返回true。

8. 运算符的优先级

建议直接加括号来控制,简单易读,不用特别去记。



参考资料

Java 运算符(引用和对象)的更多相关文章

  1. Java 超类引用子类对象的示例代码

    动态方法分配 dynamic method dispatch 一个被重写的方法的调用会在运行时解析,而不是编译时解析 Java 会根据在调用发生时引用的对象的类型来判断所要执行的方法 public c ...

  2. 理解Java的引用对象

    SoftReferenceWeakReference 的特性基本一致, 最大的区别在于 SoftReference会尽可能长的保留引用,不会在GC时就回收对象,而是直到JVM 内存不足时才会被回收(虚 ...

  3. Java多态性详解 (父类引用子类对象)

    面向对象编程有三个特征,即封装.继承和多态. 封装隐藏了类的内部实现机制,从而可以在不影响使用者的前提下改变类的内部结构,同时保护了数据. 继承是为了重用父类代码,同时为实现多态性作准备.那么什么是多 ...

  4. 深刻理解Java中形參与实參,引用与对象的关系

    声明:本博客为原创博客,未经同意.不得转载! 原文链接为http://blog.csdn.net/bettarwang/article/details/30989755 我们都知道.在Java中,除了 ...

  5. java中使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?

    java中使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 是引用对象的地址值不能变,引用变量所指向的对象的内容是可以改变. final变量永远指向这个对象,是一个常量指针,而 ...

  6. Java多态性详解——父类引用子类对象

    来源:http://blog.csdn.net/hikvision_java_gyh/article/details/8957456 面向对象编程有三个特征,即封装.继承和多态. 封装隐藏了类的内部实 ...

  7. 【Java面试题】2 Java中使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?超详细解析

    /* * 问题:使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变 * 答: * 使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的 ...

  8. Java运算符优先级(转)

    转自:http://www.cnblogs.com/gw811/archive/2012/10/13/2722752.html Java运算符优先级 序列号 符号 名称 结合性(与操作数) 目数 说明 ...

  9. 【转】Java运算符优先级

    原文网址:http://www.cnblogs.com/gw811/archive/2012/10/13/2722752.html Java运算符优先级 序列号 符号 名称 结合性(与操作数) 目数 ...

随机推荐

  1. To B服务想做移动化?腾讯云案例了解一下

    本文由 腾讯云助手团队 发布于 腾讯云云+社区 | 导语:腾讯云那么多资源和服务,就不能手机管理吗? 能. 当用户在使用To B服务时,往往会遇到各种各样的限制: 1.操作难度:涉及各种权限.多重验证 ...

  2. JAVA基于权重的抽奖

    https://blog.csdn.net/huyuyang6688/article/details/50480687 如有4个元素A.B.C.D,权重分别为1.2.3.4,随机结果中A:B:C:D的 ...

  3. WeifenLuo.WinFormsUI.Docking.dll的用法

    基本框架 说明 weiFenLuo.winFormsUI.Docking.dll是开源项目DockPanel Suite的一个类库,可以实现像Visual Studio的窗口停靠.拖拽等功能.Weif ...

  4. SQL Server 两个时间段的差and时间截取到时分

    /*--------------------------时间截取到时分-----------------------------------*/ ), ),)--返回2017-11-24 19:25 ...

  5. Java基础教程(4)--面向对象概念

      如果你之前从来没有使用过面向对象编程语言,那么在学习Java之前需要先理解几个有关面向对象编程的基本概念.这篇教程将会向你介绍对象.类.集成.接口和包的概念,以及这些概念是如何与现实世界相关联,并 ...

  6. 十五、读写锁ReentrantReadWriteLock

    一.简介 有时候我们对资源的修改操作非常地少,但是读取的频率却很高.如果采用一般的互斥锁,那么大量的读取操作也需要做等待.基于读写分离的思想,我们可以使用JDK的读写锁来处理这种情况. 1)读读不互斥 ...

  7. hdu 1880 魔咒词典 (字符串哈希)

    魔咒词典 Time Limit: 8000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  8. java 自定义泛型

    package com.direct.demo; import java.util.ArrayList; import java.util.HashMap; import java.util.Link ...

  9. bootstrap学习笔记细化(标题)

    bootstrap中的排版: 标题(h1~h6/.h1~.h6) h1:36px;h2:30px;h3:24px;h4:18px;h5:14px;h6:12px; 副标题(small) 小练习(标题大 ...

  10. css 各种常见布局整理

    在学习各种布局之前我们先来认识各个关键词,理解这些关键词,然后由点到面,这样就简单多了. display属性 页面中每个元素都有一个默认的display属性,它的值与该元素的类型有关,默认值通常是 b ...