📚变量
📕数据类型
数据类型分为基本数据类型和引用数据类型(即可以通过new
来创建对象后才能使用的数据类型)。
关键字 | 定义 | 描述 | 范围 |
---|---|---|---|
int | int i = 0; | 整数 | − 2 31 ∼ 2 31 − 1 -2^{31} \sim 2^{31}-1 −231∼231−1 |
char | char c = ‘c’; | 字符 | 0 ∼ 2 16 − 1 0 \sim 2^{16}-1 0∼216−1 |
byte | byte b = 0x00000001; | 字节 | − 128 ∼ 127 -128 \sim 127 −128∼127 |
boolean | boolean t = true; | 布尔 | t r u e ∼ f a l s e true \sim false true∼false |
float | float f = 0.5F; | 浮点 | 2 − 128 ∼ 2 128 2^{-128} \sim 2^{128} 2−128∼2128 |
引用数据类型其实就是在这些基础类型上面做了扩展,例如String
就是对char
的扩展。
public class variate{
public static void main(String[] args) {
String s = new String("23");
char c = '2';
System.out.println(s + '\n' + c);
}
}
两者之间区别就在于char
不可以使用new
来初始化值,String
则可以用new
来初始化值并创建了一个对象。在这里char
没有任何属性,而String
拥有两个属性hash
和value
。因此从意义上来说String
定义的数据是一个对象而不是变量。
💡计算原理
通过下面三个视频你可以简单地了解到计算机硬件是如何处理运算的。因为除法没有找到合适的视频,故没有设置链接。
一般结果出问题就是出现在浮点数运算中,终会有那么一点点偏差这也和二进制处理脱不了关系。
public class variate{
public static void main(String[] args) {
float a = 2.7f;
float b = 3.0f;
float res = a/b;
System.out.println(res);
}
}
及其巧妙!简单!但一般人不易看懂!CPU到底如何计算减法的?_哔哩哔哩_bilibili
神奇的电路,CPU就是靠它计算的!加法器的工作原理_哔哩哔哩_bilibili
计算机到底是如何计算乘法的?很巧巧妙的设计,只需要晶体管就能完成这个设计。_哔哩哔哩_bilibili
💡自动类型转换
public class variate{
public static void main(String[] args) {
char c = 'c';
int i = c;
float f = i;
System.out.println(c);
System.out.println(i);
System.out.println(f);
byte b = 0x01;
i = b;
System.out.println(b);
System.out.println(i);
}
}
通过这个图片可以观察到基本类型数据之间可以进行隐式转换,我们了解到char
实质上是用数值来代表字母,本质上都是转换为数值类型,因此低精度的数据类型可以向高精度的数据类型隐式地进行转换。那么有个问题就来了如何实现高精度的数据类型向低精度的数据类型进行转换?
可以通过显式地转换来满足这个需求,强制类型转换可能存在溢出的问题。
long l = 100l;
int i = (int)l;
像引用数据类型必须显式地进行强制数据转换(一般是可以将具有继承关系的对象直接转换,也可以使用对象提供的方法进行转换),因为他们是一个对象。对于具有继承关系对象之间的转换,我们必须要声明转换的类型才可以强制转换。
// 通过方法进行转换
Integer i = new Integer(100);
String s1 = i.toString();
// 通过继承关系进行转换
/**
* 只能通过子类转换为父类
* 具体原因我暂时不是很清楚
*/
class A{}
class B extends A {}
public class variate{
public static void main(String[] args) {
B b = new B();
A a = b;
B c = (B)a;
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
💡运算注意点
&&
和||
不能用于计算,只适用于条件判断可以加快程序的判断能力。byte x = 0x00; byte y = 0x01 System.out.println(x|y);// 1
+=
、-=
、/=
、*=
、%=
、&=
和|=
,在等号右边可以加符合逻辑的算术表达式并不会引起错误且等号右边整体可以看成是一个变量。int i = 2; int j = 3; int k = 1; k *= j + i; System.out.println(k);// 5 k = (i + j) * k
- 变量后
++
或--
具有一个作用域的概念,当用作循环语句的表达式时,只有当前一个循环执行一次以后才会改变值。int i = 0; for(;i<=2;i++){ System.out.println("循环第"+(i+1)+"次的值:\t"+i); } System.out.println("循环以后的值:\t"+i);
- 布尔
boolean
无法与数值直接进行转换,0
和1
都不可以。
📚引用
📕强引用、虚引用、软引用、弱引用
【强引用】:垃圾回收器永远不会回收的引用。当内存不足时,JVM会直接抛出OutOfMemoryError
;只有通过将强引用赋值为null,这样JVM可以回收对象。
Object obj = new Object(); //只要obj还指向Object对象,Object对象就不会被回收
obj = null; //手动置null 使JVM回收对象
【软引用】:在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。
import java.lang.ref.SoftReference;
【弱引用】:无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。
import java.lang.ref.WeakReference;
【虚引用】:随时可能会被回收,无法通过虚引用获取对象,必须要与ReferenceQueue引用队列一起使用。
import java.lang.ref.PhantomReference;
SoftReference、WeakReference和PhantomReference都是继承了Reference类。在Reference类里面有对引用的状态进行说明:Active
、Pending
、Enqueued
和Inactive
。
如果你是无意刷到这篇文章并看到这里,希望你给我的文章来一个赞赞👍👍。如果你不同意其中的内容或有什么问题都可以在下方评论区留下你的想法或疑惑,谢谢你的支持!!😀😀