文章目录
Java知识相关总结,包含了大部分Java相关的知识点供大家学习参考。欢饮大家阅读,有写的不对和不足的地方,还请各位大佬指点,在下感激不尽🤝🤝🤝。文章持续更新中…
序号 | 内容 | 连接地址 |
---|---|---|
1 | Java基础之入门(一) | https://blog.csdn.net/weixin_44347552/article/details/107397354 |
2 | Java基础之流程控制(二) | https://blog.csdn.net/weixin_44347552/article/details/107667815 |
Java帝国的诞生
1990年末,Sun公司成立了一个有 James Gosling 领导的“Green计划”,准备为下一代智能家电编写一个控制系统
团队很多成员发现C++在嵌入式平台方面有很大的局限性,例如:太复杂、系统资源有限、缺少垃圾回收机制、可移植性、分布式、多线程等。Sun团队决定开发一种新的语言,取名 Oak。1992年,Green团队完成了新平台的部分功能,同年11月,Green计划被转化成“FirstPerson有限公司”
FirstPerson团队在华纳公司发布电视机顶盒发布会被有限电视界认为给用户太多权利而争标失败,与3DO公司另一笔机顶盒交易也没有成功。Green项目夭折,FirstPerson团队一半成员被调
1994年夏天,互联网和浏览器出现,Gosling 意识到这是个机会,将Oka进行小规模改造,94年秋,团队中 Naughton 与 Jonathan 完成了第一个Java语言网页浏览器,因Oka被注册,改名为Java
java名字由来:java是爪哇岛咖啡名字,据说是程序员在苦思冥想该起什么名字比较好的时候,下楼点了一杯咖啡,感觉味道很不错,就命名为java
1995年初,Sun公司发布Java语言,想互联网所有用户公开,包括源代码
1. Java初生
- 图形界面的程序(Applet)
- JAVA标准版(J2SE):去占领桌面
- JAVA移动版(J2ME):去占领手机
- JAVA企业版(J2EE):去占领服务器
2. Java的发展
基于Java开发的平台、系统、工具:
- 构建工具:Maven,Ant,Jekins
- 应用服务器:Tomcat,Jetty,Jboss,Weblogic
- Web开发:Spring,Mybatis,Struts,Hibernate
- 开发工具:Eclipse,IDEA,Netbean,Jbuilder
开发历史:
- 2006:Hadoop(大数据领域)
- 2008:Android(安卓手机端)
3. Java特性和优势
简单性
是c++的纯净版,没有
头文件
,指针运算
,结构
,联合
,操作符重载
,虚基类
等等。语法基于C,因此学起来非常容易
面向对象
面向对象是一种程序设计的技术,它将重点放在
对象
和对象接口
上
可移植性
这是Java的重要优势。JAVA代码或者说字节码、二进制码可以跨平台的移植,而不用管具体的操作系统和硬件环境。JAVA本身就是面向网络的,只有在网络环境中才能显示出他的优势,比如:现在我有一个网络环境,要让我的笔记本和手机交互,笔记本环境是windows发出一个让手机定时录音的JAVA代码,手机只有简单Linux内核操作系统,照样可以完美的执行这个代码
“一次编写,随处运行”
:“write once, run anywhere”
高性能
Java语言本身发展中通过虚拟机的优化提升了几十倍运行效率。比如,通过
JIT(JUST IN TIME)
即时编译技术提高运行效率。 将一些“热点”
字节码编译成本地机器码,并将结果缓存起来,在需要的时候重新调用。这样的话,使Java程序的执行效率大大提高
分布式
Java是为Internet的分布式环境设计的,因为它能够处理TCP/IP协议。事实上,通过URL访问一个网络资源和访问本地文件是一样简单的。Java还支持
远程方法调用
(RMI,Remote Method Invocation),使程序能够通过网络调用方法
动态性
Java可以通过
反射
来动态的获取相应的对象
多线程
多线程的使用可以带来更好的
交互响应和实时行为
。多线程的简单性是Java成为主流服务器端开发语言的主要原因之一
安全性
Java适合于网络/分布式环境
,为了达到这个目标,在安全性方面投入了很大的精力,使Java可以构建防病毒,防篡改的系统
健壮性
Java是一种健壮的语言,吸收了
C/C++
语言的优点,但去掉了其影响程序健壮性的部分(如:指针
、内存
的申请与释放等)。Java程序不可能造成计算机崩溃。Java系统仔细检测对内存的每次访问,确认它是合法的,而且不致引起任何问题。不过,即使Java程序也可能有错误。如果出现某种出乎意料之事,程序也不会崩溃,而是把该例外抛弃。再通过异常处理机制,程序就会发现这类例外,并加以处理
4. JVM、JRE、JDK
JVM:Java Virtual Machine
JVM虚拟机,将编译后的字节码文件运行在任意平台上,达成了
一次编译,到处运行的跨平台性
。
JRE:Java Runtime Environment
运行时环境
,包含JVM。如果只需要在系统上运行Java程序,则只需要安装JRE即可。
JDK:Java Development Kit
JDK包含了JRE和JVM。JDK多了一些工具,如:
(1)javac:将Java'(.java)的程序文件编译成字节码(.class)文件
(2)jar:将Java程序打成jar包
(3)javadoc:将Java生成一些文档
5. Java程序的运行机制
首先,Java语言是一个半编译、半解释型语言。
(1)编译型:也就是说将文件一次性编译好,然后进行处理,效率比较高。举个例子,将中文书本翻译成英文来给外国人使用。
(2)解释性:边执行边解释,效率比较低。举个例子,外国人说一句,就翻译一次。
6.注释
Java中的注释有三种:
(1)单行注释:
// 单行注释
(2)多行注释:
/* 多行注释 */
(3)文档注释:
/**
* 文档注释
* @param ...
*/
7. 标识符和关键字
7.1 关键字
abstract | assert | boolean | break | byte |
case | catch | char | class | const |
continue | default | do | double | else |
enum | extends | final | finally | float |
for | goto | if | implements | import |
instanceof | int | interface | long | native |
new | package | private | protected | public |
return | strictfp | short | static | super |
switch | synchronized | this | throw | throws |
transient | try | void | volatile | while |
7.2 标识符
- 所有标识符的首字符都应该以字母(a-z或A-Z)、美元符($)或者下划线(_)开始
- 首字符之后可以是字母(a-z或A-Z)、美元符($)、下划线(_)或者数字的任何组合
- 不能使用关键字
- 标识符的大小写是敏感的
- 可以使用中文命名,但不建议这样使用
8. 数据类型
8.1 基本数据类型
- char(字符型):占2个字节,范围是 0~65535
- byte(字节整数型):占1个字节,范围是 -128~127
- short(短整数型):占2个字节,范围是 -32768~32767
- int(整数型):占4个字节,范围是 -2147483648~2147483647(21亿)
- long(长整数型):占8个字节,范围是 -9223372036854775808~9223372036854775807
- float(浮点型,单精度):占4个字节
- double(浮点型,双精度):占8个字节
- boolean(布尔型):占1位,只有true和false
8.1.1 字符案例
Demo1:字符转化为整型
char c1 = 'A';
char c2 = '中';
int i1 = c1;
int i2 = c2;
System.out.println("c1:"+c1);
System.out.println("c1转换为int:"+ i1);
System.out.println("c2:"+c2);
System.out.println("c2转换为int:"+ i2);
输出结果:
Demo2:字符为Unicode编码转义字符值时
char c = '\u0061';
System.out.println("c:"+c);
输出结果:
Demo1和Demo2得出结论:
字符的本质其实还是数字,经过int转换后会转换成相应的Unicode码值
Unicode和ASCII的区别:
ASCII:就是编码英文的26个字母和一些常见的符号,之后扩展了一半。总之是一个字节来做编码,大于128的部分是一些特殊符号。但ASCII是无法编码别的东西的,比如说是不存在“中文的ascii码需要2个字符”这种说法的。ASCII就只有一个字节
Unicode:是足够编码地球上所有的语言了,所以ASCII中所能表示的,Unicode当然全部包括了。Unicode本身是只有2个字节的,之所以出现UTF-8,UTF-16等等之类,那是为了针对不同的应用环境,提高整体编码效率,比如如果某篇文章里绝大部分是英语(单字节就能表示),就比较适合使用utf-8,而如果绝大部分是中文(需要双字节),可能就utf-16比较合适了
常见的转义字符
转义字符 | 意义 | ASCII |
---|---|---|
\a | 响铃(BEL) | 007 |
\b | 退格(BS) ,将当前位置移到前一列 | 008 |
\f | 换页(FF),将当前位置移到下页开头 | 012 |
\n | 换行(LF) ,将当前位置移到下一行开头 | 010 |
\r | 回车(CR) ,将当前位置移到本行开头 | 013 |
\t | 水平制表(HT) (跳到下一个TAB位置) | 009 |
\v | 垂直制表(VT) | 011 |
\ \ | 代表一个反斜线字符’’’ | 092 |
\ ’ | 代表一个单引号(撇号)字符 | 039 |
\ " | 代表一个双引号字符 | 034 |
\0 | 空字符(NUL) | 000 |
8.1.2 整型案例
int i1 = 10; //十进制
int i2 = 010; //二进制
int i3 = 0x10; //十六进制
System.out.println("i1="+i1);
System.out.println("i2="+i2);
System.out.println("i3="+i3);
输出结果:
8.1.3 浮点型案例
一些
银行业务
需要对数字进行运算,那怎么去使用呢?
看以下案例
Demo1:数值相同的float和double是否相等
float f = 0.1f;
double d = 1.0/10;
System.out.println("f:"+f);
System.out.println("d:"+d);
System.out.println("f是否等于d:"+(f==d));
输出结果:
Demo2:数值不相同的两个float是否相等
float f1 = 23131313f;
float f2 = f1+1;
System.out.println("f1:"+f1);
System.out.println("f2:"+f2);
System.out.println("f1是否等于f2:"+(f1==f2));
输出结果:
Demo1和Demo2得出结论:
最好避免使用浮点型进行比较,可以使用BigDecimal(数学工具类)来对浮点型进行计算
8.2 引用数据类型
- 类
- 接口
- 数组
9. 类型转换
在C和C++中,类型转换有时会让人头疼,但在Java中,类型转换则是一种比较安全的操作
Java允许我们把任何基本数据类型转换成别的基本数据类型,但布尔型除外,后者根本不允许进行任何类型的转换处理。
低 -----------------------------------------> 高
byte,short,char -> int -> long -> float -> double
9.1 转换方式
9.1.1 隐式转换
系统默认将其转换为我们需要的数据类型
例如:
byte b = 20;
int i = b;
9.1.2 显式(强制)转换
通过手动将类型进行转换
例如:
public class ConstraintTransition {
public static void main(String[] args) {
float f = 12.5f;
double d = 12.8;
int fi = (int)f;
int di = (int)d;
System.out.println("fi="+fi);
System.out.println("di="+di);
}
}
输出结果:
注意:
将浮点值转换为整型值时,总是对该数字执行截尾,如果想要得到四舍五入的结果,需要使用java.lang.Math中的round()方法
9.2 转换溢出
int money = 10_0000_0000;
int year = 20;
int total = money*year;
long ltotal = money*year;
System.out.println("total:"+total);
System.out.println("ltotal:"+ltotal);
输出结果:
得出结论:
在long ltotal = money*year转换之前就已经溢出,需在转换之前对money或year进行转换。如下:
int money = 10_0000_0000;
int year = 20;
long ltotal = money*(long)year;
System.out.println("ltotal:"+ltotal);
输出结果:
10. 变量
10.1 什么是变量
其实就是可以
变化
的数据称为变量
变量分为成员变量
(全局变量)和局部变量
,成员变量又分为类变量
和实例变量
Java中的变量是程序中最基本的存储单元
,其要素包括变量名
,变量类型
和作用域
注意事项:
- 每个变量都有类型,类型可以是基本数据类型,也可以是引用数据类型
- 变量名必须是合法的标识符
- 变量声明是一条完整的语句,所以要以分号结尾
10.1.1 默认初始化的值
- 整数类型:0
- 浮点类型:0.0
- 引用类型:null
- 布尔类型:false
10.2 变量作用域
10.2.1 类变量(静态变量)
在类中加了
static
关键字修饰的变量称为类变量(静态变量)。
使用之前,在声明时可以不用进行初始化
public class Variable {
static int staticVar = 1; //类变量(静态变量)
}
10.2.2 实例变量
在类中没有
static
关键字修饰的变量称为实例变量。
使用之前,在声明时可以不用进行初始化
public class Variable {
int staticVar = 1; //实例变量
}
10.2.3 局部变量
在方法中没有
static
关键字修饰的变量称为局部变量。
无论在静态方法
还是非静态方法
中都不能用static
修饰变量(等会会解释,这些需要涉及到JVM虚拟机
的知识)
使用之前,在声明时必须进行初始化
public class Variable {
public static void main(String[] args) {
int staticVar = 1; //局部变量
}
}
10.2.4 类变量、实例变量、局部变量的区别
以下括号里面的涉及到
JVM虚拟机
的知识,所以建议去了解下JVM虚拟机
,对你学习Java有很大的帮助
类变量
-
可以被访问修饰符修饰
-
类变量是存储在
(JVM虚拟机中的堆内存)
-
随着类的加载而加载,所以可以使用类名.变量名来调用
-
可以被静态方法和非静态方法所调用
-
有默认初始化值,在类加载时
(类加载有三个阶段,首先加载(loading),其次链接(linking),最后显示初始化(initialization))
,其中类变量的默认初始化就是在链接(linking)阶段的准备时期完成的
实例变量
- 可以被访问修饰符修饰
- 实例变量是存储在
(JVM虚拟机中的堆内存)
- 随着对象的创建而创建,所以需要使用对象名.变量名来调用
- 可以被非静态方法调用,不能被静态方法调用
- 有默认初始化值,在创建对象的时候
(创建对象有6个阶段,1.查看该对象对应的类是否已经被加载,2.为对象分配内存,3.处理并发安全问题,4.对实例变量进行默认初始化,5.设置对象头,6.调用init<>方法来显示初始化,代码块初始化,构造器初始化)
,其中实例变量的默认初始化是在第4步时进行的
局部变量
- 不能被访问修饰符修饰
- 不能被static关键字修饰
- 局部变量是存储在
(JVM虚拟机中的栈内存的局部变量表)
- 随着方法的加载而加载,当方法执行完成后,局部变量就销毁了
- 局部变量没有默认初始化值,所以需要在被调用之前就对其进行赋值
10.2.5 static关键字
一个
static
字段对每个类
来说都只有一份存储空间,而非static
字段则是对每个对象
有一个存储空间。
但如果static
作用于某个方法
,差别却没有那么大。static方法
的一个重要用法就是在不创建任何对象的前提下就可以调用它。这一点对定义main
方法很重要
例如:
public class User{
private static int si = 1;
private int i = 1;
public static void staticA(){
.................
}
public void A(){
.................
}
public static void main(String[] args){
//类名.调用静态变量或静态方法
User.si = 666;
User.staticA();
//对象名.调用变量和方法
User user = new User();
user.i;
user.A();
}
}
11. final常量
显示初始化(
initialization
)后不能再改变其值
常量名一般使用大写字符,存放位置不存在先后顺序
11.1 关键字
例如:
public class Variable {
final int finalV = 773;
}
11.2 作用域
修饰类
- 类不能被继承
修饰方法
- 方法不能被重写
修饰变量
- 可以修饰类变量(静态变量)、实例变量、局部变量
- 变量只能被赋值一次,然后就不能被修改,也就是常量
12. 操作符
在最底层,Java中的数据是通过使用
操作符
来操作的
- 赋值运算符:=
- 扩展赋值运算符:+=,-=,*=,/=
- 算术运算符:+,-,*,/,%,++,- -
- 关系运算符:>,<,>=,<=,==,!=,instanceof
- 逻辑运算符:&&,||,!
- 位运算符:&,|,^,~,>>,<<,>>>
- 三元运算符:true | false ?true :false
注意:
几乎所有的操作符都只能操作基本类型。例外的操作符是 “=” 、"==" 和 “!=”,这些操作符能操作所有的对象。除此之外,String类支持 “+” 和 “+=”
12.1 优先级
当一个表达式中存在多个操作符时,操作符的优先级就决定了各部分的计算顺序。其中最简单的就是
先乘除后加减
了
运算符优先级表(从上往下)
优先级 | 运算符 | 综合性 |
---|---|---|
1 | () [] | 从左向右 |
2 | ! +(正) -(负) ~ ++ – | 从右向左 |
3 | * / % | 从左向右 |
4 | +(加) -(减) | 从左向右 |
5 | << >> >>> | 从左向右 |
6 | == != | 从左向右 |
7 | () [] | 从左向右 |
8 | &(按位与) | 从左向右 |
9 | ^ | 从左向右 |
10 | | | 从左向右 |
11 | && | 从左向右 |
12 | || | 从左向右 |
13 | ? : | 从右向左 |
14 | = += -= /= %= &= |= ^= ~= <<= >>= >>>= | 从右向左 |
例如:
public class Precedence {
public static void main(String[] args) {
int a = 7;
int b = 7;
int c = 3;
int count1 = a + c - b / a;
int count2 = a + (c - b) / a;
System.out.println("count1="+count1);
System.out.println("count2="+count2);
}
}
输出结果:
注意:
System.out.println语句中包含 “+” 操作符。在这里前面是字符串,后面跟着 “+” 意味着是字符串连接,当编译器观察到一个String后面紧跟一个 “+” ,而这个 “+” 后面又紧跟一个非String类型的元素时,就会尝试着将这个非String类型的元素转换为String。例如上面的int类型的count1,count2
12.2 赋值运算符
左值必须是一个明确的、已命名的变量,且不能是一个
算术运算
(a+b)。也就是说,必须有一个物理空间可以存储=
(等号)右边的值
例如:
int a = 4;
//如下为错误例子
int a+b = 4;
12.2.1 基本类型和引用类型的区别
基本类型
基本类型存储了实际的数值,而不是指向一个对象的引用(详情请看对象章节),所以在赋值的时候,是直接将一个地方的内容复制一个副本到另一个地方
例如:
public class BaseType {
public static void main(String[] args) {
int a = 10;
int b;
b = a;
//修改b的数据,a会不会发生变化呢?
b = 5;
System.out.println("a="+a);
System.out.println("b="+b);
}
}
输出结果:
注意:
此时,它是将a的值复制一个副本赋值给b,那么如果当我们修改b的值时,a其实是不会变化的。所以也就验证了基本数据类型不是指向一个对象的引用
引用类型
引用类型操作的则是对象的引用
例如:
public class QuoteType {
public static void main(String[] args) {
User user1 = new User();
user1.name = "cjj";
user1.age = 22;
User user2;
user2 = user1;
//修改user2后,user1会不会变化呢?
user2.name = "qqf";
user2.age = 20;
System.out.println("user1="+user1);
System.out.println("user2="+user2);
}
}
class User{
public String name;
public int age;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
输出结果:
注意:
我们可以看到当user1赋值给user2,user2修改数据时,user1也跟着变化了,说明这时user1是将对象的引用赋值给了user2,这种特殊的现象通常称为别名现象
12.2.2 别名现象
相当于引用传递赋值,将
一个对象的引用赋值给另一个对象
,当修改被赋值的对象时,赋值的对象就会被修改,使其对象之间无法独立,要避免这个问题
12.3 算术操作符
12.3.1 自增++和自减–
例如:
public class Count {
public static void main(String[] args) {
int a = 1;
int b = a++;
//如果有赋值情况并且不是将值赋给自己,则这里相当于隐藏了一个 a = a + 1
System.out.println("a:"+a);
System.out.println("b:"+b);
}
}
输出结果:
12.4 关系操作符
关系操作符生成的是一个
boolean
(布尔)类型的结果,如果表达式为真则会生成true
(真),反之为false
(假)
例如:
public class Relation {
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 10;
System.out.println("a是否等于b:"+ (a==b));
System.out.println("a是否等于c:"+ (a==c));
System.out.println("a是否小于b:"+ (a<b));
}
}
输出结果:
注意:
这时就需要用到前面所说的优先级的问题,因为 “+” 的优先级大于 “==”,所以会先进行 “+” 运算,从而导致 左边为常量,右边为 == 会报错,所以需要将右边用括号括起来
12.5 逻辑操作符
逻辑操作符 “与”(&&)、“或”(||)、“非”(!)能根据参数的逻辑关系,生成一个布尔值(
true
或false
)
12.5.1 &&和&的区别
&&:
&&也称短路与运算,也就是先进行左边运算,当左边为false时,则不会进入到右边运算,直接返回false,当两边都为true时返回true
&:
在运算时分别计算表达式两边的结果,再作&运算,当两边都为true时返回true
12.6 三元操作符
三元操作符也称为条件操作符,它比较特别,因为它有三个操作数,
(true | false ? true : false)
它有点类似于if-else
(后面章节会介绍),它的类型
为?
或:
后面的值类型
例如:
public class Three {
public static void main(String[] args) {
int a = 10;
int b = 20;
String result = a==b?"相等":"不相等";
System.out.println("result="+result);
}
}
输出结果:
12.7 Java没有sizeof()
在C和C++中,
sizeof()
操作符可以告诉你为数据项分配的字节数
在C和C++中,需要使用sizeof()
最大的原因是为了移植
,因为它的数据类型
在不同的机器上的大小可能不同。
而Java的所有的数据类型
在所有机器中的大小都是相同的
,所以不需要用sizeof()
来满足这方面的需求
12.8 ==和equals区别
==:
==比较的是 内容和 地址是否相同
equals:
equals只比较内容是否相同
13. JavaDoc生成文档
用来生成java文档。
注意:
- javadoc只能为public(公共)和protected(受保护)成员进行文档注释
- 但是private可以用-private来进行标记,以便把private成员的注释也包括在内
13.1 使用DOS命令
到对应的java文件目录下
javadoc -encoding UTF-8 -charset UTF-8 类名.java
13.2 使用IDEA
参数说明
1.Whole project:整个项目都生成文档
2.Custom scope 自定义范围。如下:
(1)project files 项目文件,
(2)project production files 项目产品文件,
(3)project test files 项目的测试文件, 未知范围,class hierarchy 类层
3.include test source 包含测试目录
4.include JDK and … 包含jdk和其他的第三方jar
5.==link to JDK documentation…==链接到JDK api
6.output directy 生成的文档存放的位置
(1)private、package、protected、public 生成文档的级别(类和方法)
(2)右边的Generate…是选择生成的文档包含的内容,层级树、导航、索引…
(3)再右边是生成的文档包含的内容信息,作者版本等信息
7.Locale 语言类型,zh-CN
8.Other command line arguments 其他参数
9.Maximum heep… 最大堆栈
我这里的配置如下:
说明:
IntelliJ IDEA作为Java流行的编辑器, 其生成一些Javadoc会对中文乱码, 使用UTF-8编码即可. 这个常见的问题, 则需要生成时设置参数即可
在 “Tools->Gerenate JavaDoc” 面版的 “Other command line arguments” 栏里输入 :
传入JavaDoc的参数,一般这样写
-encoding UTF-8 -charset UTF-8 -windowtitle “文档HTML页面标签的标题” -link http://docs.Oracle.com/javase/7/docs/api
不然的话会报可能会报错误: 编码GBK的不可映射字符