自增自减运算符在写代码的过程中,常见的一种情况是需要某个整数类型变量增加 1 或减少 1,Java 提供了一种特殊的运算符,用于这种表达式,叫做自增运算符(++)和自减运算符(–)。
++ 和 – 运算符可以放在变量之前,也可以放在变量之后,当运算符放在变量之前时(前缀),先自增/减,再赋值;当运算符放在变量之后时(后缀),先赋值,再自增/减。例如,当 b = ++a 时,先自增(自己增加 1),再赋值(赋值给 b);当 b = a++ 时,先赋值(赋值给 b),再自增(自己增加 1)。也就是,++a 输出的是 a+1 的值,a++输出的是 a 值。用一句口诀就是:“符号在前就先加/减,符号在后就后加/减”。
public、protected、default、private的区别(1)default是默认的,什么都不写,在同⼀个包内是可见的,不使⽤任何修饰符。
(2)public能⽤来修饰类,在⼀个java源⽂件中只能有⼀个类被声明为public,而且⼀旦有⼀个类为public,那这个java源⽂件的⽂件名就必须要和这个被public所修饰的类的类名相同,否则编译不能通过。public⽤来修饰类中成员(变量和⽅法),被public所修饰的成员可以在任何类中都能被访问到。
(3)protected是受保护的,受到该类所在的包所保护,被protected所修饰的成员会被位于同⼀package中的所有类访问到。同时,被protected所修饰的成员也能被该类的所有⼦类继承下来。
(4)private,private是私有的,即只能在当前类中被访问到,它的作⽤域最⼩。
static关键字啥作用?这就要提到new对象,只有new对象之后,数据存储空间才会被分配,方法才能供外界所调用。但是当没有创建对象的时候也想要调用方法或者就是想为特定分配存储空间的时候,就需要用static。所以有了static,成员变量或者方法就可以在没有所属类的时候被访问了。
(1)final就是不可变的意思,可以修饰变量、⽅法和类。修饰变量时,这个变量必须初始化,所以也称为常量。(2)finally是异常处理的⼀部分,只能⽤在try/catch中,并且附带⼀个语句块表⽰这段语句⼀定会被执⾏,⽆论是否抛出异常。(3)finalize是java.lang.Object中的⽅法,也就是每⼀个对象都有这个⽅法,⼀个对象的finalize⽅法只会调⽤⼀次,调⽤了不⼀定被回收,因为只有对象被回收的时候才会被回收,就会导致前⾯调⽤,后⾯回收的时候出现问题,不推荐使用。
移位运算符是最基本的运算符之一,几乎每种编程语言都包含这一运算符。移位操作中,被操作的数据被视为二进制数,移位就是将其向左或向右移动若干位的运算。
移位运算符在各种框架以及 JDK 自身的源码中使用还是挺广泛的,HashMap(JDK1.8) 中的 hash 方法的源码就用到了移位运算符:
1234567static final int hash(Object key) { int h; // key.hashCode():返回散列值也就是hashcode // ^:按位异或 // >>>:无符号右移,忽略符号位,空位都以0补齐 return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }
在 Java 代码里使用 <<、 >> 和>>>转换成的指令码运行起来会更高效些。
掌握最基本的移位运算符知识还是很有必要的,这不光可以帮助我们在代码中使用,还可以帮助我们理解源码中涉及到移位运算符的代码 ...
在循环结构中,当循环条件不满足或者循环次数达到要求时,循环会正常结束。但是,有时候可能需要在循环的过程中,当发生了某种条件之后 ,提前终止循环,这就需要用到下面几个关键词:
continue:指跳出当前的这一次循环,继续下一次循环。
break:指跳出整个循环体,继续执行循环下面的语句。
return 用于跳出所在方法,结束该方法的运行。return 一般有两种用法:
return;:直接使用 return 结束方法执行,用于没有返回值函数的方法
return value;:return 一个特定值,用于有返回值函数的方法
思考一下:下列语句的运行结果是什么?
12345678910111213141516171819202122232425public static void main(String[] args) { boolean flag = false; for (int i = 0; i <= 3; i++) { if (i == 0) { System.out.println(&q ...
从 Java5 开始,Java 支持定义可变长参数,所谓可变长参数就是允许在调用方法时传入不定长度的参数。就比如下面的这个 printVariable 方法就可以接受 0 个或者多个参数。
123public static void method1(String... args) { //......}
另外,可变参数只能作为函数的最后一个参数,但其前面可以有也可以没有任何其他参数。
123public static void method2(String arg1, String... args) { //......}
遇到方法重载的情况怎么办呢?会优先匹配固定参数还是可变参数的方法呢?
答案是会优先匹配固定参数的方法,因为固定参数的方法匹配度更高。
我们通过下面这个例子来证明一下。
1234567891011121314151617181920/** * @date 2021/12/13 16:52 **/public class VariableLengthArgument { public static vo ...
封装封装最好理解,封装是面向对象的特征之一,是对象和类概念的主要特征,封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的就行信息隐藏。
继承它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展,通过继承创建的新类称为子类和派生类,被继承的类型为基类(父类或者超类)
多态性它是指在父类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为,这使得同一个属性或者方法在父类及其各个子类中具有不同的含义。
自动装箱与拆箱了解吗?原理是什么?什么是自动拆装箱?
装箱:将基本类型用它们对应的引用类型包装起来;
拆箱:将包装类型转换为基本数据类型;
举例:
12Integer i = 10; //装箱int n = i; //拆箱
上面这两行代码对应的字节码为:
123456789101112131415161718192021222324252627L1 LINENUMBER 8 L1 ALOAD 0 BIPUSH 10 INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer; PUTFIELD AutoBoxTest.i : Ljava/lang/Integer;L2 LINENUMBER 9 L2 ALOAD 0 ALOAD 0 GETFIELD AutoBoxTest.i : Ljava/lang/Integer; INVOKEVIRTUAL java/lang/Integer.intValue ()I PUTFIELD AutoBoxTest.n : I RETURN
从字节码中,我们发现装箱其实就是调用 ...
浮点数运算精度丢失代码演示:
12345float a = 2.0f - 1.9f;float b = 1.8f - 1.7f;System.out.println(a);// 0.100000024System.out.println(b);// 0.099999905System.out.println(a == b);// false
为什么会出现这个问题呢?
这个和计算机保存浮点数的机制有很大关系。我们知道计算机是二进制的,而且计算机在表示一个数字时,宽度是有限的,无限循环的小数存储在计算机时,只能被截断,所以就会导致小数精度发生损失的情况。这也就是解释了为什么浮点数没有办法用二进制精确表示。
就比如说十进制下的 0.2 就没办法精确转换成二进制小数:
12345678// 0.2 转换为二进制数的过程为,不断乘以 2,直到不存在小数为止,// 在这个计算过程中,得到的整数部分从上到下排列就是二进制的结果。0.2 * 2 = 0.4 -> 00.4 * 2 = 0.8 -> 00.8 * 2 = 1.6 -> 10.6 * 2 = 1.2 -> 10. ...