java是强语言机制类型,基本数据类型遵循最小作用域原则。基本数据类型的基础底层是整数类型(二进制补码形式的表示),小数类型、字符类型和布尔类型本质上就是数值类型;由字符类型衍生出String类型,进而衍生出数组、类和接口等引用类型。
分类
java 基本类型数据表如下:
switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 char上,是否能作用在 String 上
java中switch(expr )中的expr 目前只支持boolean类型表达式的限制:自jdk1.5之后支持long以下的数值(整数)类型,jdk1.7之后支持单字符和枚举类型,字符和枚举本质上也是数值类型。1.8之后支持字符串(等值比较)。
Math.round(10.5) 等于多少?Math.round(-10.5)等于多少?Math.floor(10.5) 等于多少?Math.ceil(10.5) 等于多少?
Math.round(10.5)的返回值是 11,Math.round(-10.5)的返回值是-10。四舍五入的原理是在参数上加 0.5 然后进行下取整,或者是参数减0.4进行向上取整。Math.floor(10.5)的返回值是 10,向下取整(舍1);Math.ceil(10.5)的返回值是 12,向上取整(进1)。
long a = 5;是否正确?float f = 5.6;是否正确?
long a = 5; 正确,属于自动类型转换(小到大)。
float f = 5.6; 不正确,需要强制类型转换(大到小)。强制类型转换会存在丢失精度的问题,但也不能溢出类型小的范围。
注意:
byte b = 5; 属于强制类型转换(大到小),但是不会报错,这是系统自动帮你自动转换的。
int a = 5; byte b = a; 错误。我们可以把int类型的常量直接赋值给byte、short类型的变量,但不能把int类型的变量直接赋值给byte、short类型的变量。
强制类型转换成功的条件是 :被强制类型转换的实例必须是强制类型转换类型的类或者其派生类。
byte s1 = 1; s1 = s1 + 1;有错吗?byte s1 = 1; byte s2 = 2; s1 = s1 + s2;有错吗?byte s1 = 1; s1 += 1;有错吗?
byte s1 = 1; s1 = s1 + 1; 错误。1是int类型的,s1 + 1是int类型(算术运算符的结果类型为参与算术运算的变量或常量的最大类型所决定,这个最大类型最小为int类型,如果低于int类型,系统会自动转换为int类型)int类型不能直接赋值给byte类型的变量。同理,byte s1 = 1; byte s2 = 2; s1 = s1 + s2; 错误。
而 byte s1 = 1; s1 += 1;可以正确编译,因为 s1+= 1;相当于 s1 = (byte (s1 + 1);其中有隐含的强制类型转换。
变量
变量是值可以变的储存空间,变量一般初始化为无效值。
数组是一组(固定数量)类型相同的连续的储存空间的表示。
对象是一类具有相同属性和行为的事物抽象描述。
堆和栈结论
基本数据类型、局部变量、String类型的直接赋值和引用类型的引用都是存放在栈内存中的,用完就消失。如下图所示,栈内存特点是数据一执行完毕,变量会立即释放,节约内存空间;并且必须初始化变量的值。
引用类型new创建的实例化对象、String类型的构造方法new出来的对象及数组,是存放在堆内存中的,用完之后靠垃圾回收机制不定期自动消除。如下图所示,堆内存中所有的实体都有内存地址值,系统会自动初始化变量的值;当堆内存中的实体不再被指向时,JVM启动垃圾回收机制,自动清除。而从JDK1.7开始,当堆内存中的实体不再被指向时,JVM会将地址贴上一个闲置或者垃圾标签,进行缓存处理,在一段时间内没有被再次使用,JVM才会启动垃圾回收机制进行清除该地址的空间。
java中的绑定机制,是和地址有关系的,是java值传递现象的根本所在。简单的说,就是绑定栈的就是静态绑定机制,执行完值不变化;绑定堆的就是动态绑定机制,执行完值变化。
&&与&的区别
&&运算符是短路与运算,&运算符是按位与运算。短路的意思就是当左侧的表达式能确定最终结果时,右侧表达式不执行 ,而按位与就是左右两侧的表达式不论结果都要执行。
用最有效率的方法计算 10 乘以 0.5
10 >>1(右移 1 位相当于除以 2 的 1 次方,右移 31位相当于乘以 2 的 31次方)。
位运算符和逻辑运算符的使用如下:
在实际开发中: 总比例:源码注释 = 1:3
idea快捷键: ctrl+/
//xxxxx
(2) 多行注释idea快捷键: ctrl+shift+/
/*
xxx
…
xxx
*/
(3)文档注释idea快捷键: /*+enter
/*
*xxx
*…
*xxx
*/
break、continue、return的区别
标号退出语句退出多重循环
在Java中,要想跳出多重循环,可以在外面的循环语句前定义一个标号,然后在里层循环体的代码中使用带有标号的break 语句,即可跳出外层循环。例如:
public static void main(String[] args) {
ok:
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
System.out.println("i=" + i + ",j=" + j);
if (j == 5) {
break ok;
}
}
}
}
定义
Java中,可以使用访问修饰符对类、变量、方法和构造方法的访问权限进行限制或者说保护,本身就是java封装的体现。Java 支持 4 种不同的访问权限。
分类
private : 在同一类内可见。使用对象:变量、方法、内部类。 注意:不能修饰类(外部类)。
default (即缺省,什么也不写,不使用任何关键字): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
protected : 对同一包内的类和所有子类可见。使用对象:变量、方法、内部类。 注意:不能修饰类(外部类)。基类的 protected 成员属性是包内可见的,并且对子类可见;
public : 对所有类可见。使用对象:类、接口、变量、方法。
访问修饰符图示
protected额外说明:若子类与基类不在同一包中,那么在子类中,子类实例可以访问其从基类继承而来的protected方法,而不能访问基类实例的protected方法。属性可见(子类,孙子类都可以),方法看来源于哪里,就是哪里所在的包以及子类(只有直系子类)。
final关键字的用法
final 修饰符,用来修饰类、方法和变量:
final finally finalize区别
this关键字的用法
super关键字的用法
this和super的区别
static关键字
static存在的主要意义
static的主要意义是在于创建独立于具体对象的域变量或者方法。以致于即使没有创建对象,也能使用属性和调用方法!
static关键字还有一个比较关键的作用就是用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
为什么说static块可以用来优化程序性能,是因为它的特性:只会在类加载的时候执行一次。因此,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。
static的独特之处
(1)被static修饰的变量或者方法是独立于该类的任何对象,也就是说,这些变量和方法不属于任何一个实例对象,而是被类的实例对象所共享。
(2)在该类被第一次加载的时候,就会去加载被static修饰的部分,而且只在类第一次使用时加载并进行初始化,注意这是第一次用就要初始化,后面根据需要是可以再次赋值的。
(3)static变量值在类加载的时候分配空间,以后创建类对象的时候不会重新分配。赋值的话,是可以任意赋值的!
(4)被static修饰的变量或者方法是优先于对象存在的,也就是说当一个类加载完毕之后,即便没有创建对象,也可以去访问。
static使用常被认为共享数据
(1)被static修饰的属性和方法被称之为类属性与类方法,无须对象,通过类名就可以访问
(2)但是static违背了OOP,JVM启动时装载字节码文件工程中创建所有静态内容,当JVM关闭时static内容才会消耗
(3)何时使用:使用频次高,且当前工程中许多类需要用
(4)静态方法只能访问静态属性和静态方法
static应用场景
因为static是被类的实例对象所共享,因此如果某个成员变量是被所有对象所共享的,那么这个成员变量就应该定义为静态变量。
因此比较常见的static应用场景有:修饰成员变量 、修饰成员方法 、静态代码块 、修饰类【只能修饰内部类也就是静态内部类】 、静态导包。
static注意事项
静态只能访问静态。非静态既可以访问非静态的,也可以访问静的。