每日一问,百日百问
1. byte 类型转换
(1) byte b=1;
b=b+1;
(2) byte b=1;
b+=1;分别写出上面两段代码编译是否通过,
不通过,解释原因。
public class demo1 {
public static void main(String[] args) {
/*
会报错, 需要将byte 类型的 和 int类型 进行一个强制转换
*/
byte b = 1; // 默认未超过byte的范围: -128 ~ 127 => 则默认转换为 byte型
b = b + 1; // 就没有底层帮忙惹~ 得自己手动进行强转
System.out.println(b); // 编译错误
/*
b += 1 => 会自动将int类型转换为byte
为什么呢 ?
底层写好了的, b = (byte) b + 1; 底层进行强转
*/
byte b = 127;
b += 1;
System.out.println(b); // b = -128
}
}
拓展 =>
向上转换:
整型,字符型,浮点型的数据在混合运算中相互转换,转换时遵循以下原则:
容量小的类型可自动转换为容量大的数据类型;
byte, short, char → int → long → float → double
byte,short,char之间不会相互转换,他们在计算时首先会转换为int类型
boolean 类型是不可以转换为其他基本数据类型
2.break 和 continue的区别
break
=> 到break语句的时候, 直接跳出当前循环体结束循环
continue
=> 跳过当前作用域中此次的循环内容, 继续执行下一次循环
3. 循环之间的区别(for 和 while)
while() => 先判断后执行
do…while => 先执行后判断
for 和 while 的区别 =>
一开始都是使用由 while 主导的循环模式
=> 后来演变为了for()循环这样的格式
定义循环变量 => 判断循环条件 => 更新循环变量
//定义循环变量
int i = 0;
//判断循环条件
while(i<10){
System.out.println(i);
//更新循环变量
i++;
}
和for循环相比, for循环定义的变量在循环结束时会进行变量的回收;
而while循环定义变量在循环体之外, 循环结束后可继续使用
所以for() 和 while() 相比, 主要就是变量的一个不同叭~
for()的特殊形式
死循环 =>
for(定义循环变量;true;更新循环变量)
for(System(1);true(默认) ; sout(2)){
sout(3)
}
运行结果 => 1 3 2 3 2 3 2 3 2 3 2 3 2 3 2...
4. 接口和抽象类的区别
- 接口的使用体现了多态性, 方法的不同表现形态, 可以多次进行重写
- 一个类可以实现多个接口,
- 接口不能定义构造器 => 不能实例化 (接口里面都是抽象方法, 不能实例化)
接口
- 接口内定义的静态方法, 只能通过接口调用
- 类优先原则 (接口的方法调用优先级较低)
- 若多个接口定义同名同参数方法, 实现类未对其重写, 会报错
相同点 =>
- 都不能实例化
- 都可以包含抽象方法
不同点 =>
- 实现类只能单继承, 但可以多实现
- 接口与接口之间可以实现多继承, 抽象类只能实现单继承
- 抽象类中一定有构造器,便于子类实例化时调用; 接口不能有构造器
5. static可以用来修饰什么, 且修饰后有什么特点以及如何使用 ?
static, 静态关键字, 可以修饰类和变量, 修饰后, 可创建出独立于具体对象的域变量或者方法
-
当类加载时就加载到内存, 且独有一份
-
被static修饰的变量属于类的静态资源, 在类实例之间共享
-
静态不能访问非静态, 非静态可以访问静态!
使用方式 => 不需要通过对象进行访问, 类被加载后可通过类名直接进行访问
6. 根据自己的理解说一下ArrayList 和 LinkedList 的区别
ArrayList =>
-
底层数据结构是数组, 从而相比LinkedList占用内存更小
-
数组, 增删慢, 查找快
LinkedList =>
- 底层数据结构是双向链表, 除了存储内容还需存储两个引用值, 占用内存更快
- 链表, 增删快, 查找慢
7. 谈谈final, finally, finalize的区别
final
是最终修饰符, 它所修饰的类不能被继承, 修饰的方法不能被覆盖, 所修饰的常量被初始化后不能被修改
finally
是捕获异常时, try-catch-finally 最后的 由finally修饰的代码块意思为最后代码结束时必定执行的代码块
finalize
作用 => 对象被垃圾收集器析构之前调用 => 用来清除回收对象
注:
1. JVM始终只调用一次finalize() (不算主动调用的次数)
2. 一般不使用, finalize()只在系统进行GC的时候才会被使用用来清理特殊的内存
8. Collection 和 Collections的区别
Collection => 接口
为各种集合提供了统一的操作方式
Collections => 包装类
有关集合操作的静态方法, 类似于一个工具类, 直接使用, 不能被实例化
eg:
//排序
Collections.sort(list);
9. Overload 和 Override 的区别, Overloaded 的方法是否可以改变返回值的类型 ?
Overload 是重载 =>
发生在相同类当中, 可以改变返回值的类型(若参数完全一样则不行), 方法名称相同, 参数值和返回类型可不同
Override 是重写 =>
发生在子父类当中, 且方法名称和参数值相同, 重写(覆盖)了父类的方法
10. 写出接口和抽象类的区别?
接口 : 抽象类
所有的方法都是抽象的 : 抽象类可包含抽象和非抽象方法
多实现 : 单继承
实现接口必须实现接口声明的所有方法 : 不用全部实现抽象类的方法
接口的成员函数默认是public : 抽象类可以是private, protected, public
### 9.实现线程的几种方式
```java
//第一种 直接继承Thread 调用start()
MyThread m = new MyThread();
m.start();
//第二种 创建任务对象并传给创建的新线程
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
//第三种 带返回值的线程Callable
1. 编写类实现Callable接口 , 实现call方法, call方法会返回计算结果 <T>
class XXX implements Callable<T> {
@Override
public <T> call() throws Exception {
return T;
}
}
2. 创建FutureTask对象 , 并传入第一步编写的Callable类对象
FutureTask<Integer> future = new FutureTask<>(XXX);
3. 通过Thread,启动线程
new Thread(future).start();