start方法和线程优先级
class Test8 {
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
my360DW();
}
};
// t.start(); // DW360
// t.run(); // 360DW
// default // DW
System.out.print("DW");
}
// static method
static void my360DW() {
System.out.print("360");
}
/*
t.run()只是简单的方法调用
所以先执行方法再执行System.out.print语句
而t.start()开启了一个线程t1
然后t1和main线程一起执行
main线程比t1优先级高
所以先输出DW
然后main线程结束
再执行t1线程的run方法
输出360
*/
}
try,catch,finally语句块执行情况
class Demo {
public static void main(String[] args) {
System.out.print(getNumber(0));
System.out.print(getNumber(1));
System.out.print(getNumber(2));
System.out.print(getNumber(4));
/*
try,catch,finally中:
num=0,捕获异常,执行catch语句,catch中返回0
执行finally语句,finally语句中返回-1,于是返回finally中的-1
num=1,try中返回2,执行finally语句
finally语句中返回1,于是返回finally中的1
num=2,try中返回1,执行finally语句
finally语句中没有返回,于是返回try中的1
num=4,try中返回0,执行finally语句
finally语句中没有返回,于是返回try中的0
规则:
1. try块是必须的,catch块和finally块都是可选的
但必须存在一个或都存在。try块不能单独存在
2. try块里的语句运行中出现异常会跳过try块里其他语句
直接运行catch里的语句
3. 无论try块中是否有异常,无论catch块中的语句是否实现,都会执行finally块里的语句
4. 如果try块或catch块中有return语句,finally块里的语句会执行在try块或catch块中的return语句前
也就是finally块return的优先级比try和catch要高
5. 如果finally块里有return语句,则直接返回
而不执行try块或catch块里的return语句
6. 只有一种办法不执行finally块里的语句,那就是调用System.exit(1);方法
即退出java虚拟机
重点:finally块里的语句在try或catch里的人return前执行
throw语句也一样finally执行了throw,try和catch里面的throw都失效了
注意:int类型的值计算出来如果是分数,会自动向下取证
比如int i = 1/2;
输出i = 0
*/
}
public static int getNumber(int num) {
try {
int result = 2 / num;
return result;
} catch (Exception exception) {
return 0;
} finally {
if (num == 0) {
return -1;
}
if (num == 1) {
return 1;
}
}
}
}
符号位操作
class Test2 {
public static void main(String[] args) {
new Test2().test();
}
public void add(Byte b) {
b = b++;
}
public void test() {
Byte a = 127;
Byte b = 127;
add(++a);
System.out.print(a + " ");
add(b);
System.out.print(b + "");
}
/*
基本类型的值是保存在栈内存里面的
每个方法都有自己的栈内存
所以add(++a)里面的操作对test()里面的a并没有什么影响
对于Byte数据类型
++a会溢出,++a的结果是1000 0000
又因为最高为为符号位
1表示负数,java用补码来表示负数
所以它的值应该要减1再取反
减1:0111 1111
再取反:1000 0000所以表示的是-128
add(b)操作对test()里面的b值没影响
所以b = 127
Byte是byte的包装类,运算操作都是对Byte.value进行的
byte 8位,最高位是符号位
add方法不改变值,但是++a会
127 = 01111111(2)
加一得到
10000000
这是一个补码,并且是负数,各位取反再加一得到10000000(2) = 128
所以第一个输出-128
(2)表示2进制
*/
}
自动装箱和自动拆箱
class Test10 {
public static void main(String[] args) {
Integer integer1 = new Integer(17);
Integer integer2 = new Integer(17);
Integer integer3 = 17;
Integer integer4 = 17;
Integer integer5 = new Integer(400);
int i = 17;
System.out.println(integer3 == integer4); // true
System.out.println(integer1 == integer2); // false
System.out.println(i == integer1); // true
System.out.println(i == integer5); // false
}
/*
考察的是基本类型装箱/拆箱对象引用(内存地址)是否相同
Integer a1=17实际上执行了Integer.valueOf(17);
就是自动拆箱/装箱的过程
Integer.valueOf方法会把传进来的数据类型转换为int类型变量
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.***[i + (-IntegerCache.low)];
return new Integer(i);
}
i和Integer比较的时候,Integer会自动拆箱,比较的是数值的大小
但是如果超过-128~127,就不能触发自动拆箱
*/
}
类变量和实例变量
/*
下列程序的输出结果是
*/
class Pass{
static int j = 20;
public void amethod(int x){
x = x*2;
j = j*2;
}
public static void main(String args[]){
int i = 10;
Pass p = new Pass();
p.amethod(i);
System.out.println(i+" and "+j);
// 10 and 40
/*
amethod方法中
值传递
返回值void
x值不变
j属于类变量
不允许非法前后引用
举个栗子
public class ErrorDef {
static int num1 = num2 + 5;
static int num2 = 20;
}
就是不能这么写
但实例变量可以这么引用
public class RightDef {
int num1 = num2 + 5;
static int num2 = 20;
}
重点:类变量属于该类本身,只要类变量初始化完成
在类范围内都可以使用该类变量
*/
}
}
二维数组基地址计算
/*
假设以行序为主序存储二维数组A=array[100][100]
设每个数据元素占2个存储单元,基地址A[0][0]为10
则A[5][5]的地址为()
正确答案: A
1,020
818
808
1,010
根据公式
基地址+(n(i-1)+j-1)b = 10+(100*5+5)*2=1020
其中i表示二维数组所在行数
其中j表示二维数组所在列数
其中b表示每个元素存储单元长度
根据题意
i = j = 6
b = 2
所以
A[5][5]的地址为:5*100*2+5*2+10 = 1020
千万不要忘记基址是10,不是0
*/
表示最小的整数
/*
由 4 个 "1" 和 4 个 "0"
组成的 8 位二进制补码
能表示的最小整数是:
正确答案: C
-125
-32
-121
-3
注意问的是补码
补码转原码加1取反
如果要表示最大数
首位必须为0
且绝对值部分最大
01111000(complementary, original)
num = 120
如果要表示最小数
首位必须为1
且补码绝对值部分最小
10000111(complementary)
10000110(inverse)
11111001(original)
num = -121
*/
补充知识点
/*
收集了一些常见的小知识点
就是一些常识性问题
看看这些放松一下吧
*/
/*
第2行代码的作用是什么
*/
public class Tree {
public static void main(String[] args) {
Tree tree = new tree();
Tree[] trees = new trees[10];
/*
应该只是创建长度为10的空数组
而数组里面只能放Tree类型的元素
比如String string[] = new String[10];
是一个道理
*/
}
}
/*
i最终输出多少
*/
class Test9 {
public static void main(String[] args) {
int i;
for (i = 2; i <= 10; i++) {
System.out.println(i);
}
System.out.println(i); // 11
/*
可以看出
i在外部声明,作为局部变量
受到for循环影响
最终输出结果为11
*/
}
}
/*
java默认引用的包是java.lang包
*/
/*
如果一个类声明实现一个接口,但没有实现接口中的所有方法
那么这个类必须是abstract类
*/
interface Person {
void method1();
}
abstract class John implements Person{}
/*
随机存取
比如数组,顺序链表
内存地址连续
访问效率高
顺序存取
比如链表
存储结构有两个域
数据域和指针域
访问需要从前往后遍历
增删效率高
索引存取
比如二叉搜索树
散列存取
比如哈希表
每个hashcode对应1个值
两者都一定的相似性,可以加快检索速度,是一种存储结构。
但是索引的方式相当于给一个本书加一个目录,这样子就可以快速找到每一个章节
好处就是增加检索速度,坏处就是增加了书的厚度,而且如果改变了书的内容,目录也要动态更新。
索引底层数据结构一般是B+树。
B+树的优点就是层数少,能够快速查找。当然也有缺点:就是插入的时候速度比顺序插入慢。
散列(哈希)可以不是连续地存储,它不是相当于一本书,而是通过某一个散列函数
把原本书的每一页放到某一本空白笔记本上
因为能通过关系查找到,也有目录,但是增加改动基本不用动态地改全部目录
*/