JDK、JRE、JVM区别与联系
JDK(Java Development Kit)Java开发工具包:JRE+Java开发工具,包含编译工具(Javac.exe),打包工具(jar.exe)等
JRE(Java Runtime Environment)Java 运行时环境:JVM+Java核心类库lib,核心类库主要包括:java.lang包等,JRE大部分由C和C++编写
JVM(Java Virtual Machine)Java虚拟机:Java程序运行在虚拟机上,不同平台有自己的虚拟机,因此Java语言可以实现跨平台
Java程序编译运行
字节码:Java源代码由编译器编译后产生的文件叫做字节码文件,只面向虚拟机,不面向特定的处理器。一定程度上解决传统解释型语言执行效率低的问题,同时保留可移植的特点。无需重复编译便可在多种不同的计算机上运行(一次编译到处运行)
Java源代码-->编译器-->.class字节码-->JVM中解释器-->.java二进制机器码-->程序运行
Java基本数据类型
类型 | 关键字 | 占用内存 | 取值范围 | 默认值(成员变量) |
整型 | byte | 1字节 | -128(-2^7)~127(2^7-1) | 0 |
short | 2字节 | -32768(-2^15)~32767(2^15-1) | 0 | |
int | 4字节 | -2147483648~2147483647(2^31-1) | 0 | |
long | 8字节 | -2^63~3^63-1 | 0 L | |
浮点型 | float | 4字节 | -3.403E38~3.403E38 | 0.0f |
double | 8字节 | -1.798E308~1.798E308 | 0.0d (不加后缀默认为双精度) | |
字符型 | char | 2字节 | 'a' 'A' '我’ | '\u0000' |
布尔型 | boolean | 1字节 | true、false | false |
short s = 1;s += 1;自增自减有隐含的强制类型转换 s = (short)(s + 1);
访问权限修饰符
private 当前类中,使用对象:内部类、变量、方法
default (缺省、不使用任何关键字)同一包中,使用对象:类、接口、变量、方法
protected 同一包中、所有子类,使用对象:内部类、变量、方法
public 所有类可见,使用对象:类、接口、变量、方法
运算符
&和&&的区别
&:按位与、逻辑与;
&&:短路与运算,虽然逻辑与和短路与都要求运算符两端的布尔值为true,表达式值才为true,但短路与如果&&左边的表达式值为false,右边的表达式会直接被短路掉,不会进行运算。|和||差别也如此。
关键字
final finally finalize 的区别
final用于修饰类、方法、变量,修饰类不可被继承,修饰方法不可被重写,修饰变量不可以被改变(不能被重新赋值),被final修饰不可变的是变量的引用,而不是引用指向的内容。
finally一般出现在try-catch代码块中,在处理异常时,我们通常将一定要执行的代码放在finally代码块中,不管是否出现异常,该代码都会执行,一般用来存放一些释放资源的代码,如:流的关闭。
finalize是Object类中的一个方法,该方法一般由垃圾回收器来调用,当我们调用System.gc()时,由垃圾回收器调用finalize(),作某对象是否可回收的最后判断。
this super关键字区别
this指当前对象,Java关键字,本质上是一个指向本对象的指针
当形参与成员变量同名时,用this区分,指代成员变量 this.name = name;
引用本类的构造函数 this()
super指当前对象的直接父类中的成员,是一个Java关键字
当子类成员变量或方法与父类中成员变量或方法同名时,用super区分 supre.name; super();
在Java中通常定义一个不做事且无参的构造方法
Java程序在执行子类构造方法之前,如果没有super()来调用父类构造方法,则会调用父类中无参构造,若父类中只定义了有参构造时,且在子类构造方法中又没有通过super()调用父类构造方法,则编译出错;在调用子类构造方法之前先调用父类无参构造可以帮助子类作初始化工作。
this()和super()均需放在构造器第一行;均不可以在static环境中使用。
static关键字
修饰成员变量、成员方法、代码块、内部类、静态导包
被static修饰的变量或方法是属于类的,不需要通过对象调用就可以使用;被所有类的实例对象所共享;
静态块可以在类中任何地方,可以有多个代码块,在类被初次加载时,会按照静态块的顺序执行,并且只执行一次。因此我们通常将只需要初始化一次的操作都放在静态块中,如程序中需频繁读取的静态资源,但后面根据需要是可以再次赋值的。
static变量在类加载时被分配空间,以后创建类对象的时候不会重新分配。
静态代码块可以优化程序性能。
静态只能访问静态(静态方法可以不通过对象调用,因此静态方法里,不能调用其他非静态变量),在静态方法中不存在this;
非静态既可以访问非静态,也可以访问静态的。
break continue return的区别
break 用于跳出循环体,结束当前循环;
continue 用于跳出本次循环,继续执行下一次循环;
return 程序返回,不再执行下面的代码,代表方法执行完毕。
面向对象编程
面向对象和面向过程的区别
面向过程:具体化,流程化,解决一个问题,这一步怎么做下一步怎么做,
如:把大象装冰箱需要几步;
优点:性能比面向对象高,因为类调用时需要实例化,开销比较大。单片机、Linux、Unix等一般采用面向过程开发;
缺点:没有面向对象易维护、易复用、易扩展。
面向对象:模型化的,抽象出一个类,这个类中有你所需的数据也有解决问题的方法,需要什么功能直接用就好了。无需关注功能是如何实现的,比委托他人买早餐,我们只需要拿到早餐就可以,不需要关心他是走哪条路去的,怎么去的;
优点:易维护、易复用、易扩展
缺点:性能比面向过程低
注:面向对象底层还是面向过程,把面向过程抽象成类,然后封装,便于我们使用就是面向对象。
面向对象三大特性
封装
将一段有关联的代码以某种形式包装起来,将内部细节以权限控制的形式按需进行隐藏,对外部只提供相应的访问接口,比如:方法的封装、类的封装、app的封装,封装之后,用户无需关心内部复杂的实现细节,因此使功能的使用变得简单,其次内部功能实现只需外部参数传递不再需要其他,具有较好的内聚性,封装后复用性更好,可以多次重复调用;
继承
子类通过继承获取父类的属性和方法(私有成员不能继承、构造方法不能继承),首先提高代码的复用性,其次为多态中类型转换提供基础。
多态
分为行为多态和类型多态,行为多态:一个类型的引用指向不同子类时同一个方法的调用会有不同的结果(同一类型对于不同对象由不同的体现),类型多态:同一个对象可以根据需要转换或强制转换为其继承或实现过的所有类型(同一对象作为不同类型时有不同的行为),然后调用对应类型中的独特方法。
类和接口
抽象类和接口的区别
抽象类 | 接口 | |
声明 | 抽象类由abstract关键字声明 | 接口由interface关键字声明 |
实现 | 子类通过extends关键字继承抽象类,需在子类中重写所有抽象方法 | 子类通过implements关键字实现接口,需在子类中重写所有抽象方法 |
构造器 | 可以有构造器 | 不能用构造器 |
访问修饰符 | 抽象类中方法可以是任意访问修饰符 除private | 接口方法默认访问修饰符是public 并且不可定义为private或protected |
多继承 | 一个类只能继承一个抽象类 | 一个类可以实现多个接口 |
字段声明 | 抽象类的字段声明可以是任意的 | 接口中字段默认为常量 |
抽象类主要体现同一类型的特征,当有共同属性和方法体需要提取时,使用抽象类;(用来提供类的模板,当需要定义子类行为,又要为子类提供通用功能时,采用抽象类)
接口指行为的抽象,是一种行为规范,当有某种操作结果、操作方式需要提取时选用接口;规范行为应优先选择接口而非抽象类,因为Java只支持单继承;在复杂的代码中,一般既有接口又有抽象类,其中抽象类用来复用代码,接口用来对外提供标准访问,比如集合框架中的List和AbstractList
普通类和抽象类
普通类不能包含抽象方法,抽象类可以包含普通方法;
抽象类不能实例化。
变量和方法
成员变量和局部变量
成员变量 | 局部变量 | |
定义 | 在方法外部、类内部定义的变量 | 类的方法中定义的变量 |
作用域 | 整个类中有效 | 方法内部有效 |
存储位置 | 存储在堆内存中 | 存储在栈内存中 |
生命周期 | 随对象创建而存在,对象回收而消失 | 方法被调用时产生,调用结束释放 |
初始值 | 由初始默认值 | 无初始默认值,使用前必须赋值 |
静态变量和实例变量
静态变量:不属于任何实例对象,属于类,在内存中只有一份,在类加载过程中,JVM值为静态变量分配一次内存空间;
实例变量:每次创建对象,都会为每个对象分配内存空间,实例变量属于实例对象,内存中,创建几次对象,就有几份成员变量;
构造方法
方法名与类名相同,无返回值,不能用void生命构造函数,生成类对象是自动执行,无需调用。
重写和重载
重载:不同的多个方法,发生在同一类中,方法名相同参数列表不同(参数类型、参数个数、顺序不同),与方法返回值个访问权限无关;
重写:同一个方法的不同体现,发生在父子类之间,方法名相同、参数列表相同、子类返回值类型小于等于父类、抛出异常类型小于等于父类、访问权限修饰符大于等于父类(向上造型,通过父类方法定义调用子类重写后方法体,若方法名和参数列表不同,则无法调用到对应的子类方法;若子类访问权限为private,则无法调用;若子类返回值类型大于父类,则父类无法接受;若子类抛出异常大于父类,父类无法处理);若父类方法访问修饰符为private则子类中就不是重写,而是一个新的方法。
==和equals()的区别
==:比较基本数据类型,则比较具体的值;比较引用数据类型,则比较对象的地址;
equals():equals()是Object类中一个方法,他的底层仍由==实现,比较对象地址,我们通常重写该方法用于比较两个对象是否相等;我们常用的String类已经重写了equals()。
hashCode和equals的关系
hashCode()的作用是获取哈希码,也成为散列码;返回一个int整数,通过哈希码来确定该对象在哈希表中的索引位置。以HashSet为例,当你想把对象加入HashSet时,首先会计算哈希值来判断对象要加入的位置,若该位置已存在对象,这时会调用equals()来检查对象是否真的相同;若相同,插入失败;若不同,重新散列到其他位置。这样大大减少了equals的次数,相应的大大提高了执行速度。
若两个对象相等,则hashcode一定也相等;
两个对象有相等的hashcode值,不一定相等。
hashCode()对堆中对象产生独特值。若没有重写hashCode(),则该类的两个对象无论如何都不会相等(即使俩个对象指向相同的数据)。
值传递和引用传递的区别
值传递:在方法调用时,传递的参数是值的拷贝,即传递之后就互不相关了;(基本数据类型)
引用传递:在方法调用时,传递的是引用的地址,传递的是值的引用,即原对象与形参指向同一个引用。(引用数据类型)
Java中有哪些常用包
java.lang 运行Java程序系统类(基本数据类型、基本数学函数、字符串处理、线程、异常处理类)
java.io 与输入输出有关的类,如:文件操作
java.util 系统辅助类,如:集合
java.sql 数据库操作类