1.Java历史:
1995年Sun公司推出,最初命名Oak(橡树)。
口号:一次编译,到处运行。
Java技术体系:面向桌面应用开发J2SE,面向企业级开发J2EE,面向手机等移动终端开发J2ME。
2009年Oracle公司收购Sun公司。
2.SDK,软件开发包,主要包含函数库或工具;
JDK,Java程序开发工具包,面向Java程序的开发者;
JRE,Java程序运行环境,面向Java程序的使用者;
API,应用程序编程接口;
API Documentation,API说明文档,描述API中的类、方法等使用的方式。
3.安装JDK需要配置环境变量,JAVA_HOME,PATH,CLASSPATH:
JAVA_HOME:指定JDK的安装目录;
PATH:把JDK中Java命令所在目录配置到原有的PATH中,可以配置到PATH的最前面,这里可以不引用JAVA_HOME的变量值,直接配置JDK安装目录的bin目录就行;
CLASSPATH:指定要运行加载的class文件所在位置,配置一个点(.)就行。
4.JDK包括JRE,JRE包含JVM。
5.jdk目录下:
bin目录存放jdk相关的命令;
db目录是jdk自带的一个小型数据库;
include目录是用于存放JVM启动时需要引入一些C语言的头文件;
jre目录的JDK自带的一个Java运行环境;jre–server–jvm.dll
lib目录提供了一些Java类库和库文件,也就是jar包;
src.zip文件:压缩文件,存放JDK核心类的源代码,也就是JavaSE-API的源代码。
rt.jar:rt就是运行时环境,java文件编译后生成的class文件都存放在里面。
ext.jar:让扩展类加载器去自动加载这个jar中的class文件到内存中,这样我们的代码就可以直接使用到这个jar中的类了。
6.API文档就是一本说明书,用来指导我们该如何调用这些别人提供给我们的基本代码。
7.Java是什么?
Java是一门编程语言,包含基本语法、特性、思想等;
Java是开发环境,Java程序的开发工具;
Java是应用环境,给开发好的Java程序提供一个运行环境;
Java是部署环境,给其他平台下开发出来的Java程序提供一个最基础的部署环境。
8.Java的优点:
更纯粹的面向对象编程,加速开发的过程。
一次编写/编译,到处运行,代码可以跨平台。
多线程的支持。
代码中没有指针管理、内存管理,使得编程人员可以更加专注于系统的业务功能的开发。
字节码的验证机制,保证代码的安全性。
开源及强大的生态环境,社区活跃,第三方类库选择丰富。
9.JVM:Java虚拟机在计算机的内存中,虚拟并提供了Java代码可以在其中运行的基础环境。JVM就是Java代码和计算机之间的一个桥梁。
java代码编译后,可以在不同的操作系统平台中运行的原因是什么?(跨平台)
java程序是在java虚拟机上运行的,在不同的操作系统中只要安装java虚拟机就可以运行Java环境。
10.字节码验证:编写好的java代码,编译成class(字节码)文件后,再被JVM加载到内存中的时候,是需要做字节码验证的。
字节码验证主要包含:
检查当前class文件的版本和JVM的版本是否兼容;
检查当前代码是会破坏系统的完整性;
检查当前代码是否有栈溢出的情况;
检查当前代码中的参数类型是否正确;
检查当前代码中的类型转换操作是否正确。
11.字节码验证后,JVM要进行解释/JIT:
解释执行:JVM解释一行代码就执行一行代码。
JIT:即时编译,JVM可以把Java中的热点代码直接编译成计算机可以运行的代码,下次调用这个热点代码,计算机就可以直接运行,可以提供运行效率。
12.常用的命令:javac编译命令,java运行命令,javadoc生成API文档命令,javap反编译命令,jar打包命令。
13.JavaSE-API常用的包:
java.lang包里面的类可以直接使用,不需要导入;
java.awt,java.swing,java.awt.event三个包都是用于图形化界面的;
java.io包下的类主要用于输入输出流,读数据/写数据;
java.net包下用于网络编程;
java.util包下是常用工具类。
14.定义类相关问题:
1)类是组织代码的基本单元。
2)main方法是作为java程序的唯一入口而存在的。
3)在自己的类中,想使用别人/自己提前写的另一个类,需要满足以下要求:.java文件要编写完成并已经编译成.class文件,.java文件在src.zip中,.class文件在rt.jar中。JVM启动时,会自动读取rt.jar中的.class文件和其他class文件。要使用其他类的class文件,需要用import语句导入。
4)java xxx运行这个类时,JVM是通过CLASSPATH环境变量配置的路径找到xxx.class文件的。
5)能否看到JVM启动xxx类之前,确实从rt.jar中加载到了其他要引用到的类?java -verbose xxx即可,java -verbose xxx > a.txt表示把读取到的加载过程的信息重定向输入到了a.txt中。
6)如果文件中的类是public修饰的,xxx这个类的名字和xxx.java的名字就要一模一样;如果不是public修饰,就可以不同。
15.package是类的命名空间,用来唯一标识这个类,避免类的名字重复。
一个指定package的类,编译后该如何运行?
java文件编译完成后,会被jvm加载到内存中,进行字节码验证后,jvm对字节码文件同时进行解释执行和即时编译的操作,对代码进行解析,最终得到运行结果。
16.类的名字有两种:简单类名,就是直接一个类名;全限定名,包名加类名。
17.在Ubuntu如何编译运行一个类?
javac -d:指定位置自动创建和包名对应的目录结构,并把编译好的class文件自动存放到里面;
java -cp:-cp是指-classpath的意思,表示执行当前java命令的时候,临时指定classpath一次,只生效一次;
javap -verbose xxx.class:用于查看某个类对应的JDK版本;
jar -cvf xxx.jar Xxx.class:把Xxx.class文件打包到xxx.jar包中;
18.类加载:java中的类,想要运行就必须把类对应的class文件加载到内存,JVM中真正负责加载class文件内容的是类加载器。
(1)启动类加载器 bootstrapClassLoader,非java语言实现,负责在JVM启动的时候,把JRE环境中最重要的一些library加载到内存。
java_home\jre\lib
作用:加载指定路径中jar里面的class文件。
(2)扩展类加载器 ExtClassLoader,java语言实现,是ClassLoader类型的对象。最常使用的就是应用类加载器,因为它可以通过CLASSPATH中的路径,去加载程序员自己编写并编译的class文件到内存中。
作用:加载指定路径中jar里面的class文件( 只能是jar中存在的class)。
java_home\jre\lib\ext
(3)应用类加载器 AppClassLoader,java语言实现,是ClassLoader类型的对象。
CLASSPATH里面的.class文件
作用:加载指定路径中class文件或者jar里面的class文件。
19.多个类加载器之间共同协作,然后把需要使用或运行的类加载到内存去执行,它们直接共同合作的方式就是双亲委托机制。
向上委托,向下加载。
20.垃圾回收机制?
程序员可以通过System.gc()或者Runtime.getRuntime().gc()来通知系统进行垃圾回收,会有一些效果,但是系统是否进行垃圾回收仍然不确定。jvm回收对象前,会先调用它的finalize方法。
1.注释:
程序中的注释是用来说明某段代码的作用的,可以增强代码的可读性,代码中的注释不会出现在字节码文件中,因为编译器会自动忽略源代码中的注释部分。
注释种类有三:
//单行注释;
/多行注释/;
/*文档注释/
ctrl+/:单行,多个单行注释
(单行注释只需选中行)
ctrl+shift+/:多行注释
ctrl+shift+:多行取消注释
(多行注释要选中指定内容)
多行注释不能嵌套。
在Java中,文档注释也被用于生成API文档。如果在生成API文档的时候,希望得到更详细的信息可以使用javadoc标记,常用的javadoc标记有:
@author:作者;
@version:版本;
@deprecated:不推荐使用的方法、过时的方法;
@param:方法的参数类型;
@return:方法的返回类型;
@see:用于指定参考的内容;
@exception:抛出的异常;
@throws:抛出的异常,和exception同义。
javadoc -d api -sourcepath src -subpackages com -author -version
-sourcepath:指定源代码存放的位置
-subpackages:指定要递归查找的包的名字
2.符号:
分号;用于结束一句代码。用的到分号的情况有:包的声明语句,类的引入语句,属性的声明语句,方法中要执行的代码。
标示符:在java中,给类、方法、变量起的名字。
标示符的命名规则:
标示符可以由字母、数字、下划线_ 、美元符号$组成;
标示符开头不能是数字;
标识符中的字符大小写敏感;
标识符的长度没有限制;
标示符不能使用java中的关键字或保留字。
关键字:const和goto是java中的保留字。
goto语句允许把控制无条件转移到同一函数内的被标记的语句。因为goto使得程序的控制难以跟踪,不建议使用。
true和false不是关键字,而是boolean类型的字面值,不能直接用来做标示符。
3.基本数据类型有8种:byte,short,int,long,float,double,char,boolean。
八大基本数据类型的大小关系?
byte–>short–>int–>long–>float–>double
char–>int
包装类:为了分别把这八种基本类型的数据,包装成对应的类类型,把它们变成对象,就可以调用方法或者访问属性。
boolean java.lang.Boolean
byte java.lang.Byte
short java.lang.Short
int java.lang.Integer
long java.lang.Long
float java.lang.Float
double java.lang.Double
char java.lang.Character
自动拆箱和自动拆箱的源码?
自动装箱:基本数据类型->包装类;
自动拆箱:包装类->基本数据类型。
new 包装类名(基本数据类型);
//创建包装类对象
new2个包装类对象,进行equals比较时,先调用包装类对象的方法:包装类对象.xxxValue();再进行比较。
基本数据类型和包装类进行比较的时候,包装类会先转换成基本数据类型,再进行值的比较。这个自动拆箱的过程调用方法:"包装类.xxxValue()"获取到包装类的数值,这个数值的对应的基本数据类型。而自动装箱时会通过"包装类.valueOf(基本数据类型变量)"的方式,把基本数据类型的数据转换成包装类。
常见编码:
ASCII:最通用的单字节编码系统,只用一个字节的7位,一共表示128个字符。
ISO-8859-1:国际标准化组织(ISO)为西欧语言中的字符制定的编码,用一个字节(8位)来为字符编码,与ASCII字符编码兼容。
GB2312:对简体中文字符的编码,一共收录了7445个字符(6763个汉字+682个其他字符)。GBK是对字符GB2312的扩展,一共收录了21886个字符(21003个字符+其他字符)。
Unicode:收录所有语言文字中的字符,分为两种编码方案:USC-2是2个字节(16位)编码,USC-4是4个字节(32位)编码。
UTF:常用的UTF字符编码包括UTF-8,UTF-16,UTF-32。UTF-8是可变长度的编码方式。
4.整数:byte、short,int和long都是整数类型,并且都是有符号整数(正负)。
byte 8位、 1字节 范围:负2的7次方~2的7次方减1
short 16位、2字节 范围:负2的15次方~2的15次方减1
int 32位、4字节 范围:负2的31次方~2的31次方减1
long 64位、8字节 范围:负2的63次方~2的63次方减1
八进制数以“0”开头,十六制以“0x”开头,二进制以“0b”开头。
浮点数:float和double都是java中的浮点型,浮点型可以用来表示小数,它们的二进制表示方式和整型不同。
float是32位,1符号位+8指数位+23尾数位。float的精度为7位左右有效数字。4个字节。
double是64位,1符号位+11指数位+52尾数位。double的精度为16位左右有效数字。8个字节。
5.引用类型:类类型、接口类型、数组类型。
6.java是面向对象的编程语言,在面向对象的思想,万事万物皆为对象。
代码中如何获得对象?
分析事物–》定义类–》声明属性/方法/构造器–》编写main方法–》创建对象–》使用对象访问属性、调用方法–》完成功能。
7.引用类型变量,简称引用,可以用来接收对象,也可以叫做引用指向对象。
基本数据类型和引用类型的区别?
/核心区别:是否可以指向对象。/
–基本数据类型只能接收基本类型数据,是一种比较简单的数据,没有属性,也没有方法。
值是不可变的;
不可以添加属性和方法;
赋值:简单赋值;
比较:基本数据类型的比较是值的比较;
存储位置:存放在栈区中。
–引用类型变量只能接收引用类型数据,也就是只能接收对象。
值可以改变的;
可以添加属性和方法;
赋值:对保存在栈区中的引用的赋值;
比较:引用类型的比较是比较引用指向的地址值是否相等;
存储位置:引用类型同时保存在栈区和堆区中:栈区中保存的是变量的标识符,堆区中保存的是变量的地址值。
基本数据类型变量和引用类型变量的核心区别:是否可以指向对象。
8.变量
变量的作用:
(1)用来接收、保存、传递、操作数据。
(2)变量的类型和数据的类型必须是一致的。
(3)如果类型不一致,那么就需要进行类型转换(自动转换,手动转换)。
变量的使用:
(1)一定是要求先声明、再赋值、再使用。
(2)也可以在声明变量的同时进行赋值,然后再使用。
变量的种类:
(1)通过类型划分:基本类型变量(byte short int long float double char boolean);引用类型变量(类类型、接口类型、数组类型)。
(2)通过范围划分:局部变量;实例变量。
如何实现交互两个变量的值,但不使用中间变量?
//使用中间变量的情况
int a = 1;
int b = 2;
int temp = a; //a:1 b:2 temp:1
a = b;//a:2 b:2 temp:1
b = temp;//a:2 b:1
//不是使用中间变量,使用+ -操作
int a = 1;
int b = 2;
a = a+b;//a:3 b:2
b = a-b;//a:3 b:1
a = a-b;//a:2 b:1
//不是使用中间变量,使用^操作
int a = 1;
int b = 2;
a = a^b;
b = a^b;
a = a^b;
一个子类型的变量一定能转换为它的父类型吗?一定。
一个父类型变量一定能强转为一个子类型吗?父类的变量一定要指向子类对象,否则不能强转。
9.局部变量定义在方法中。实例变量定义在类中,方法外。
局部变量的作用范围:直接包裹的大括号中,整个方法中。
实例变量的作用范围:当前类中所有的非静态方法都可以访问。
实例变量就是类中的属性,也叫做成员变量(非静态的)。
实例变量是有默认值的:
byte类型,默认值为0
short类型,默认值为0
int类型,默认值为0
long类型,默认值为0L
float类型,默认值为0.0F
double类型,默认值为0.0D
boolean类型,默认值false
char类型,默认值是’\u0000’
引用类型,默认值是null
10.操作符:赋值、比较、相等、算术、移位、条件操作符,位、逻辑运算符。
比较操作符中instanceof的作用是判断对象是否属于指定类型。
/*
+:可以用于拼接两个字符串,数值+字符串也可以进行拼接,连接后的结果仍是字符串。
*/
/*
>>:算术右移 位运算符:
操作的本质就是除以2^n,n就是右移的位数。
除以2^n之后,只保留整数部分。
正数右移后,左边补0;负数右移后,左边补1。
*/
/*
<<:左移 位运算符:本质就是乘以2^n,n就是左移的位数。
无论正数负数左移后,左边都是补0。
当左移后,得到的数字已经超过当前类型所能表示的最大值时,这个值会被限定到这个当前类型中。
如果移动位数超过该类型的最大位数,那么编译器就会对移动的位数取模/取余。
例如:如果对int类型移动33位,实际上只移动了1位;如果对int类型移动32位,实际只移动了0位。
*/
/*
>>>:逻辑右移 位运算符:
本质是除以2^n,n就是右移的位数。
除以2^n之后,只保留整数部分。
正数和负数右移后,左边补0。
*/
/*
^:异或运算:相同为0,不同为1。
*/
&和&&有什么区别?
&可以作为二进制数字的位运算符,也可以作为布尔表达式中的逻辑运算符,但作为逻辑运算符时没有&&那种短路的功能。&&的短路功能就是如果满足第一个要求,才会继续判断第二个要求。
条件操作符:三目运算符,boolean表达式?表达式1?表达式2。
11.类型转换:隐式转换(手动转换),显式转换(强制类型转换,手动转换)。
(1)基本数据类型:
隐式转换:数据范围比较小的,自动可以转换成数据范围类型比较大的(类型大小仅用在描述基本数据类型的时候)。
显式转换:通过在右边的数据前面加上(类型)进行强转,但因为是把范围大的数据赋值给范围小的,所以可能出现数据丢失。浮点型数据如果强转成整数,小数部分就会被全部抹去。
(2)引用类型:
隐式转换的特点:子类类型的变量可以自动转换为父类类型。
显式转换:父类类型需要强制转换为子类类型。
12.String对象:
字符串String,是程序中使用最多的一种数据,JVM在内存中专门设置了一块区域(字符串常量池),来提高字字符串对象的使用效率。
(1)创建字符串对象,和其他普通对象一样,会占用计算机的资源(时间和空间),作为最常用的数据类型,大量频繁的创建字符串对象,会极大程度地影响程序的性能。
JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化:
1)为字符串开辟一个字符串常量池,类似于缓存区;
2)创建字符串常量时,首先会检查字符串常量池中是否存在该字符串,如果存在该字符串,则返回该实例的引用,如果不存在,则实例化创建该字符串,并放入池中。
3)有变量参与拼接字符串,那么就不会使用常量池了。只有用双引号,里面加入文字的方式,才会利用到内存中的字符串常量池。
4)使用+拼接的字符串也会利用字符串常量池。但是有要求:参与+号拼接的必须是双引号的形式才可以。
5)intern方法可以在JVM在运行期间,强行使用字符串常量池。当调用 intern() 方法时,JVM会将字符串添加到常量池中,并返回指向该常量的引用。
检查当前调用intern方法的字符串,是否在常量池中,如果在那么就返回常量池中的这个对象,如果不在,那么就把当前这个调用intern方法的字符串存到常量池,供后面的代码使用。
为什么String效率低?
因为String类就是字符串是常量,它们的值在创建之后不能更改。
String对象底层是用字符数组value[]保存字符内容的。
字符串常量存储在字符串常量池,目的是共享。字符串非常量对象存储在堆中。
字符串对象怎么存储?
(1)常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
(2)只要其中有一个是变量,结果就在堆中。
(3)如果拼接的结果调用intern()方法,返回值就在常量池中。
StringBuffer的常用方法:
StringBuffer append(xxx)
//提供了很多的append()方法,用于进行字符串拼接
StringBuffer delete(int start,int end)
//删除指定位置的内容
StringBuffer replace(int start, int end, String str)//把[start,end)位置替换为str
StringBuffer insert(int offset, xxx)
//在指定位置插入xxx
StringBuffer reverse()//把当前字符序列逆转
public int indexOf(String str)
public String substring(int start,int end)
public int length()
public char charAt(int n )
public void setCharAt(int n ,char ch)
StringBuffer的反转方法:
import java.util.function.Consumer;
/*
* @author chouhan
*/
public class Homework1 {
public static void main(String[] args) {
reversal("avaj",(str)->{
String newstr=new StringBuffer(str).reverse().toString();
System.out.println(newstr);
});
}
public static void reversal(String str,Consumer<String> consumer){
consumer.accept(str);
}
}
String,StringBuffer,StringBuilder的区别?
可变性:String是一个final类,是不可变的字符序列,用字符数组保存字符串;StringBuffer和StringBuilder都是可变序列,都继承自AbstractStringBuilder类,也是字符数组char[] value保存字符串,但没有final关键字修饰。
是否线程安全:StringBuffer的方法被synchronized修饰,加同步锁使得StringBuffer线程同步,StringBuilder非线程安全。
性能,速度的比较:StringBuilder效率最高;StringBuffer略慢,但这个慢要在进行很大的数据操作时才会体现出来;String效率最低。String类型要进行改变时,都会生成新的String对象,然后将指针指向新的String对象。而StringBuffer和StringBuilder每次都是对对象本身进行操作。
适用于三者的场景:String–操作少量的数据,StringBuilder–单线程操作字符串缓冲区下操作大量数据,StringBuffer–多线程操作字符串缓冲区下操作大量数据。
java.math包和java.lang.Math类的区别?
System.out.println(2-1.1);//默认使用的是int和double类型
java.math包下的常用类:BigDecimal
BigDecimal类中的常用方法:
加法add,除法divide,乘法multiply,减法subtract。
equals比较BigDecimal(“2.00”)和BigDecimal(“2.0”)时,会比较精度,返回false。所以要用BigDecimal比较数值时,要通过compareTo比较两个对象:bg.cpmpareTo(num);。返回1表示bg>num,返回0表示返回bg=num,返回-1表示bg<num。
“exit” equals(一个对象):为什么把字符串写前面,因为如果没有给这个对象赋任何值,就会出现空指针异常。
java.lang.Math类的常用方法:
abs绝对值,ceil取整,max最大值,min最小值,random随机数[0,1)。