目录
为什么static方法中不能使用this/super关键字?
JDK和JRE的区别
JRE(Java Runtime Enviroment)是Java的运行环境。面向Java程序的使用者,而不是开发者。如果你仅下载并安装了JRE,那么你的系统只能运行Java程序。JRE是运行Java程序所必须环境的集合,包含JVM标准实现及 Java核心类库。它包括Java虚拟机、Java平台核心类和支持文件。它不包含开发工具(编译器、调试器等)。
JDK(Java Development Kit)又称J2SDK(Java2 Software Development Kit),是Java开发工具包,它提供了Java的开发环境(提供了编译器javac等工具,用于将java文件编译为class文件)和运行环境(提 供了JVM和Runtime辅助包,用于解析class文件使其得到运行)。如果你下载并安装了JDK,那么你不仅可以开发Java程序,也同时拥有了运 行Java程序的平台。JDK是整个Java的核心,包括了Java运行环境(JRE),一堆Java工具tools.jar和Java标准类库 (rt.jar)。
执行Java代码流程
- 1. 编写Java源码(源码)
- 2. 通过javac命令对代码进行编译,得到.class字节码文件(.class)
- 通过java命令将.class交给JVM(机器码)
如何判断数据类型?
方法一:getClass().getName();
方法二:instanceof
Object o = new Object();
System.out.println(o.getClass().getName()); //输出数据类型
boolean b1 = o instanceof Integer;
System.out.println(b1); //判断是否为Integer数据类型
Object类的六个方法
- wait()
- notify() / notifyAll()
- equals() 用于判断调用的对象与传递的参数的对象的地址是否相同
- hashcode() 输出调用对象的哈希码值(也就是内存地址的编号)
- getClass() 返回一个Class对象
-
toString() 输出该对象的内存地址(类名@哈希码值)
什么时候需要重写 equals 方法
equals方法默认比较的是地址值,想要让equals比较实际内容,那么就需要重写equals方法
equals重写代码(示例)
当参数对象和调用equals()方法的对向的类型相同时才需要比较它们的内容是否相同
public boolean equals(Object obj){
if(this=obj){
return true;
}
if(obj==null)
{
return false;
}
if(this instanceof student){
if(this.getId()==obj.getId()){ //重写Student类id相等时 为 true
return true;
}else{
return false;
}
}
return false;
}
HashCode和equals的关系
两个对象 equals的时候,hashCode必须相等,
但hashCode相等,对象不一定equals。
比如hashmap
HashCode用来寻找哈希桶,equals用来寻找哈希桶中链表的值
当equals都相等了,说明肯定在同一个哈希桶中,则hashcode相同
当hashcode相同,说明在一个哈希桶中,但不代表equals相同(链表中不止一个元素)
必须重写hashCode()的情况
如果你的对象想放进散列存储的集合中(比如:HashSet,LinkedHashSet)或者想作为散列Map(例如:HashMap,LinkedHashMap等等)的Key时,在重写equals()方法的同时,必须重写hashCode()方法。
hashcode就是提高效率,你想想,如果你重写了hashCode(),只要不满足第一个条件,那就直接可以判断两个对象是不等的,也就不用花费时间再去比较equals了。
为什么static方法中不能使用this/super关键字?
static叫静态方法,也叫类方法,在类加载的时候,就会为static方法分配一块内存空间,成为静态区,属于这个类。
在实例化对象的时候JVM在堆区分配一个具体的对象,this指针指向这个对象。也就是说,this指针是指向堆区中的类的对象,而static域不属于this指向的范围所在,所以不能调用。
i++ 和 ++i
i++:先执行后累加
++i:先累加后执行
public static void main(String[] args) {
int m = 10;
int x = ++m; // x = 11
int x = m++; // x = 10
}
提示:在 for 循环中,i++ 和 ++i 是一样一样的,但是++i的循环耗时短。
Java八大基本数据类型
类型名称 | 关键字 | 占用内存 | 取值范围 |
---|---|---|---|
字节型 | byte | 1 字节 | -128~127 |
短整型 | short | 2 字节 | -32768~32767 |
整型 | int | 4 字节 | -2147483648~2147483647 |
长整型 | long | 8 字节 | -9223372036854775808L~9223372036854775807L |
单精度浮点型 | float | 4 字节 | +/-3.4E+38F(6~7 个有效位) |
双精度浮点型 | double | 8 字节 | (小数默认)+/-1.8E+308 (15 个有效位) |
字符型 | char | 2 字节 | ISO 单一字符集 |
布尔型 | boolean | 1 字节 | true 或 false |
Java 默认的浮点型为 double,例如,11.11 和 1.2345 都是 double 型数值。
如果要说明一个 float 类型数值,就需要在其后追加字母 f 或 F,如 11.11f 和 1.2345F 都是 float 类型的常数。
double i = 3.14;
int j = 3;
double x = i+j;
System.out.println(x); //6.140000000000001
Java三大引用类型
类 Class
接口 Interface
数组 [ ]
运算符优先级
优先级 | 运算符 | 简介 | |
---|---|---|---|
1 | [ ] 、 . 、 ( ) | 方法调用,属性获取 | |
2 | !、~、 ++、 -- | 一元运算符 | |
3 | * 、/ 、% | 乘、除、取模(余数) | |
4 | + 、 - | 加减法 | |
5 | <<、 >>、 >>> | 左位移、右位移、无符号右移 | |
6 | < 、<= 、>、 >=、 instanceof | 小于、小于等于、大于、大于等于 | |
7 | == 、!= | 2个值是否相等 2个值是否不等 | |
8 | & | 按位与 | |
9 | ^ | 按位异或 | |
10 | | | 按位或 | |
11 | && | 短路与 | |
12 | || | 短路或 | |
13 | ?: | 条件运算符 | |
14 | =、 += 、-= 、*= 、/=、 %=、 &=、 |=、 ^=、 <、<= 、>、>= 、>>= | 混合赋值运算符 |
Java异常分类
运行时异常和编译时异常区别:
运行时异常可以不处理。当出现时,由虚拟机接管。
编译时异常必须自己处理,出现这种异常时要么throws,要么catch
运行时异常
- NullPointerException - 空指针异常
- ClassCastException - 类转换异常
- IndexOutOfBoundsException - 下标越界异常
- ArithmeticException - 计算异常
- IllegalArgumentException - 非法参数异常
- NumberFormatException - 数字格式异常
- UnsupportedOperationException 操作不支持异常
- ArrayStoreException - 数据存储异常,操作数组时类型不一致
- BufferOverflowException - IO 操作时出现的缓冲区上溢异常
- NoSuchElementException - 元素不存在异常
- InputMismatchException - 输入类型不匹配异常
编译时异常
- SQLException :提供有关数据库访问错误或其他错误的信息的异常
- IOexception :表示发生了某种I / O异常的信号。此类是由失败或中断的I / O操作产生的一般异常类
- FileNotFoundException :当试图打开指定路径名表示的文件失败时,抛出此异常。这里的找不到是在你的编译结果文件夹里面找不到
- ClassNotFoundException :找不到具有指定名称的类的定义。( 属于编译时异常,是在classloader加载类的时候发现类不存在在类路径的时候报出的。)
- EOFException :当输入过程中意外到达文件或流的末尾时,抛出此异常。( 这个一般是因为阻塞引起的,因为server的input.read读不到东西就会阻塞,当你关掉client的时候,server就知道没有东西进来了,所以就报了个异常,其实这个是正常的,只是告诉你,该把socket关闭一下,还有input也关闭一下。)
异常处理 throw 和 throws 关键词
区别
1. throws是用来声明一个方法可能抛出的所有异常信息,throws是将异常声明但是不处理,而是将异常往上传,谁调用我就交给谁处理。
2. 而throw则是指抛出的一个具体的异常类型。自己处理异常
throw
用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。
使用格式:
throw new xxxException(“异常产生的原因”);
注意:
Throw关键字后边创建的是RuntimeException或者是RuntimeException的子类对象。我们可以不处理默认交给JVM处理(打印异常对象,中断程序)。
public static void main(String[] args) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException("运行时异常");
}
}
如果throw关键字后边创建的是编译时异常,我们就必须处理这个异 常,要么throws,要么try…catch。
//抛出异常
public static void main(String[] args) throws SQLException {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new SQLException("编译时异常");
}
}
//try catch 处理异常
public static void main(String[] args) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
try {
throw new SQLException("编译时异常");
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
以后(工作中)我们首先必须对方法传递过来的参数进行合法性校验,如果参数不合法,那么我们就必须使用抛出异常(编译时异常)的方式,告知方法的调用者,传递的参数有问题。
throws
声明异常,例如,如果一个方法里面不想有任何的异常处理,则在没有任何代码进行异常处理的时候,必须对这个方法进行声明有可能产生的所有异常(其实就是,不想自己处理,那就交给别人吧,告诉别人我会出现什么异常,报自己的错,让别人处理去吧)。
异常 Exception 和错误 Error 的区别
错误:程序你运行不了
异常:程序运行到异常那一行会终止,并报出异常,除非你处理了,处理了还可以继续运行
自动装箱和自动拆箱
java是一门面向对象的语言,一切皆是对象
自动装箱:基本类型——>对象
public class Test {
public static void main(String[] args) {
// 声明一个Integer对象,用到了自动的装箱:解析为:Integer num = Integer.valueOf(9);
Integer num = 9;
}
}
自动拆箱:对象——>基本类型
对象时不能直接进行运算的,而是要转化为基本数据类型后才能进行加减乘除
public class Test {
public static void main(String[] args) {
/ /声明一个Integer对象
Integer num = 9;
// 进行计算时隐含的有自动拆箱 intValue()方法
System.out.print(num--);
}
}
int 和 Integer 有什么区别?
- Integer是int的包装类;int是基本数据类型;
- Integer变量必须实例化后才能使用;int变量不需要;
- Integer实际是对象的引用,指向此new的Integer对象;int是直接存储数据值 ;
- Integer的默认值是null;int的默认值是0。
== 和 equals 的区别
在基本数据类型中,只有==,比较的是数值是否相同;
在引用数据类型中,==用于比较两个引用数据的地址是否相同,equals()方法默认继承object类的equals方法,equals()默认比较两个引用数据的地址是否相同,程序员一般重写比较数值是否相同。
注意:
String类 和 Integer类 重写了equals方法,重写为比较值是否相同
Integer i = -128~127 内使用的是常量池,== 和 equals 都相同
Integer i = 200 等于 new Integer(200),==不相同,equals相同
static 关键字
static关键字可以声明静态变量,静态方法,静态代码块,它们都属于类,不属于类的实例对象。
静态变量在类加载时就创建了,所有静态变量,静态方法,静态代码块都不能调用实例化对象中的属性和方法
final 关键字
final 关键字表示对象是最终形态的,对象是不可改变的意思。
1. final 修饰类中的属性
表示该属性一旦被初始化其值不可改变,这里不可改变的意思对基本类型来说是其值不可变,而对对象属性来说其引用不可再变。其初始化可以在两个地方:一是其定义处,也就是说在 final 属性定义时直接给其赋值;二是在构造函数中。这两个地方只能选其一,
2. final 修饰类中的方法
继承之后不能重写final方法,但是继承类可以继续使用final方法。
3. final 修饰类(String类)
表示该类是无法被任何其他类继承的。
java 基本数据类型 int 的默认初始值问题
成员变量默认 0
局部变量必须设置初始值
public class Printer {
int x;
float y;
double z;
char v;
public static void main(String[] args) {
Printer printer = new Printer();
System.out.println("int "+Printer.x); //0
System.out.println("float "+Printer.y); // 0.0
System.out.println("double "+Printer.z); // 0.0
System.out.println("char "+Printer.v); //
}
}
Java常见问题
|| 和 && 和 | 和 & 的区别
- 我们将 || 和 && 定义为逻辑运算符,而 | 和 & 定义为位运算符。
- && (且)如果两个操作数都1,结果为1;
- || (或)如果两个操作数中有任意一个为1,结果为1。
& 按位与操作,按二进制位进行"与"运算。运算规则:(有 0 则为 0)
0&0=0; 0&1=0; 1&0=0; 1&1=1;
| 按位或运算符,按二进制位进行"或"运算。运算规则:(有 1 则为 1)
0|0=0; 0|1=1; 1|0=1; 1|1=1;
可以看出 & 和 && ( | 和 || )在判断语句中都可以实现“和”这个功能,区别在于 & 两边都运算,而 && 先算 && 左侧,若左侧为 false 那么右侧就不运算了
线程的 run() 和 start() 有什么区别?
- 调用 start() 方法是用来启动线程的,轮到该线程执行时,start()方法会新开一个线程并且执行重写run()方法,然后自动调用 run();
- 直接调用 run() 方法,无法达到启动多线程的目的,相当于主线程线性执行 Thread 对象的 run() 方法。
- 一个线程对线的 start() 方法只能调用一次,多次调用会抛出java.lang.IllegalThreadStateException 异常;run() 方法没有限制。