至今为止的Java学习
1.什么是Java
特点
Java是一门面向对象的编程语言,吸收了c++语言的各种优点,移除了c++的一些:多继承、指针等概念,Java语言是一种伪动态的对象编程语言的代表
注意:Java并不是没有了指针和多继承,多继承可以通过接口的方式来进行实现,而指针是将原来的开发人员操作改成JVM来进行操作的,并且还提供了自动分配和回收内存等功能
冷知识:Java一开始是准备叫做C++--的
Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点
Java分为了:JavaSE【桌面应用程序】、JavaEE【web应用程序】、JavaME【嵌入式开发】
起源
1996年1月,Sun公司发布了Java的第一个开发工具包(JDK 1.0),这是Java发展历程中的重要里程碑,标志着Java成为一种独立的开发工具
1998年12月8日,第二代Java平台的企业版J2EE发布。1999年6月,Sun公司发布了第二代Java平台(简称为Java2)的3个版本:
J2ME(Java2 Micro Edition,Java2平台的微型版),应用于移动、无线及有限资源的环境;
J2SE(Java 2 Standard Edition,Java 2平台的标准版),应用于桌面环境;
J2EE(Java 2Enterprise Edition,Java 2平台的企业版),应用于基于Java的应用服务器。Java 2平台的发布,是Java发展过程中最重要的一个里程碑,标志着Java的应用开始普及。
1999年4月27日,Oracle 公司开发的HostSopot HotSpot虚拟机发布。HotSpot虚拟机发布时是作为JDK 1.2的附加程序提供的,后来它成为了JDK 1.3及之后所有版本的Sun JDK的默认虚拟机
2009年,甲骨文公司宣布收购Sun
2014年,甲骨文公司发布了Java8正式版【至今还是使用最广的Java1.8】
JDK与JRE
问题1:什么是JDK它与JRE又是什么关系?
JDK是开发人员使用的开发工具包,开发Java程序就必须要使用JDK
JRE是使用人员用到的运行时环境,里面包含了JVM【它是JAVA之所以能够跨平台的关键】
JDK(Java Development Kit)称为Java开发包或Java开发工具,是一个编写Java的Applet小程序和应用程序的程序开发环境。JDK是整个Java的核心,包括了Java运行环境(Java Runtime Environment),一些Java工具和Java的核心类库(Java API)。不论什么Java应用服务器实质都是内置了某个版本的JDK。主流的JDK是Sun公司发布的JDK,除了Sun之外,还有很多公司和组织都开发了自己的JDK,例如,IBM公司开发的JDK,BEA公司的Jrocket,还有GNU组织开发的JDK
JRE是个运行环境,JDK是个开发环境。因此写Java程序的时候需要JDK,而运行Java程序的时候就需要JRE。而JDK里面已经包含了JRE,因此只要安装了JDK,就可以编辑Java程序,也可以正常运行Java程序。但由于JDK包含了许多与运行无关的内容,占用的空间较大,因此运行普通的Java程序无须安装JDK,而只需要安装JRE即可
2.一切的起源:"hello,word"
工具推荐使用:IntelliJ IDEA 、安装jdk 、配置环境变量 【我与百度进行了合作,请搜索:Java安装详细教程】
导包关键字 包名
package com.example.javademo;
建类关键字 类名
class JavademoApplicationTests {
访问修饰符 static修饰字 返回值 方法名 (数据类型 形参名 ) public static void main(String[] args) { //main线程是Java的启动的默认线程,是程序启动的入口,当然你也可以自己创建线程
数据类型 变量名 = "内容" String hello = "hello,word";
输出(变量名) System.out.println(hello); } }
从一个很简单的程序我们大概看出来一个Java的整体结构了,这样我们又离成为大牛更近一步了
Java关键字
【简单来说:有功能的字符】
Java关键字是Java里事先定义的,有特别意义的标识符,有时又叫保留字,还有特别意义的变量。Java的关键字对Java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等,关键字不能用作变量名、方法名、类名、包名和参数。
各种名:包名、类名、变量名、常量名.....
【具体的代码要求可以去阿里巴巴开发文档细看】
强制要求【报错了就知道】:
1.不能和Java关键字冲突
2.不能以字母开头
3.组成:必须由大小写字母、数字、下划线或者美元符号组成。
软性要求【不报错,但是代码很屎】:
1.包名以 com.xxxx或org.xxxx 全小写命名:mystudent、loveyou
2.类名以大写开头后面用驼峰命名法: MyStudent、LoveYou、这种格式
3.变量以小写开头后面用驼峰命名法: myStudent、loveYou、这种格式
4.常量以全大写加下划线命名法: MY_STUDENT、LOVE_YOU 这种格式
5.Java的文件名是以 xxx.java为后缀的【字节码文件为xxx.class】
访问修饰符
问题:什么是访问修饰符呢?
访问修饰符就是这个类或方法能够使用的范围,不同的范围有不同的修饰符
问题:有哪几个访问修饰符呢?
从大到小一次排列为:public、protected、默认的、private
访问级别 |
访问控制修饰符 |
同类 |
同包 |
子类 |
不同的包 |
公开 |
public |
√ |
√ |
√ |
√ |
受保护 |
protected |
√ |
√ |
√ |
-- |
默认 |
没有访问控制修饰符 |
√ |
√ |
-- |
-- |
私有 |
private |
√ |
-- |
-- |
-- |
数据类型
问题:什么是数据类型,在Java中有几种数据类型
当创建变量的时候,需要在内存中申请空间【涉及JVM】,而Java数据类型能够让内存管理根据数据为变量分配存储空间,分配的空间只能用来存储该类型的数据
Java中分为了:引用类型、基本类型
java中的引用类型是指除了基本数据类型之外的所有类型。
问题:什么是自动装箱和拆箱
简单一点说,装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型,这些拆装都是隐性的内部完成的,当然你也可以手动拆。数据类型.valueOf
1 //自动装箱 2 Integer total = 99; 3 4 //自动拆箱 5 int totalprim = total;
八大基本数据类型和对应的引用类型
整形:byte、short、int、long
浮点型:float、double、
布尔型:boolean
字符型:char
基本类型 |
boolean |
byte |
char |
short |
Int |
long |
float |
double |
void |
取值范围 |
true和false |
-128~127 |
存储Unicode码 |
-32768~32767 |
-2的31次方~2的31-1次方 |
负的2的63次方到正的2的63次方减1。 |
3.4e-45~1.4e38 |
4.9e-324~1.8e308 |
-- |
二进制位数 |
1 |
8 |
16 |
16 |
32 |
64 |
32 |
64 |
-- |
封装器类 |
Boolean |
Byte |
Character |
Short |
Integer |
Long |
Float |
Double |
Void |
数据类型转换
类型转换分为两种:显性转换【强行转换】 、隐性转换【自动转换】
byte、short、int、long、 float、double 、char 从小到大来经行转换
可以这么去想:小杯子里的水 倒入 大杯子里 可以倒入
大杯子里的水 倒入 小杯子里 也不是不能倒【但是水会溢出来【丢失精度】】
结论:
1.小类型转大类型不需要强转 例如:int-->float 隐性转换
2.大类型转小类型需要强转 例如:float-->int 强行转换 【使用idea alt+回车可以快速帮助转换】
引用类型
Java中常用的类型就是引用类型
Java中的引用类型是指除了基本数据类型之外的所有类型。
Java中有四种引用类型,分别是强引用、软引用、弱引用和虚引用。引用类型和原始类型具有不同的特征和用法。
四种引用类型
强引用 |
最常见的就是强引用,将对象赋值给一个引用变量,处于可达性无法被jvm回收 |
软引用 |
软引用需要用 SoftReference 类来实现,内存足够就不会被回收
|
弱引用 |
弱引用需要用 WeakReference 类来实现,cg运行就会回收
|
虚引用 |
虚引用需要 PhantomReference 类来实现,它不能单独使用,必须和引用队列联合使用。虚引用的主要作用是跟踪对象被垃圾回收的状态。
|
变量
在Java中的几种变量
变量的定义: 数据类型 变量名 = 内容
局部变量 和全局变量
局部变量
1.局部变量必须赋初值;
2.局变的作用域是方法内部,方法执行完毕自动销毁;
3.当局变与全局的名字一样时,局部优先;
全局变量
1.全局变量就是从定义的位置起,作用域覆盖整个程序范围的变量;
2.静态变量:static int a; 属于整个类,可以直接使用,也可 类名.a ,静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。静态变量均有默认值,数字默认为0,布尔值默认为false,对象默认为null;
3.实例变量:int a; 实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。
常量
常量在程序运行时是不能被修改的,一般用final 关键字修饰,平时写常量最好重新创建一个类用于全局的存放常量
public class constant{
public static final String COUNT="111";
}
这样平时,无论在哪里都能使用到这个COUNT的常量了:Constant.COUNT就能使用了
Java 数组
String[] args,这个就是一个char类型的数组 ,带有中括号的就是一个数组
数组是一种有序性的线性表,用来存储固定大小的同类型元素
数组是储存在堆上的对象,可以保存多个同类型变量,后面再细讲
输出语句
System.out.println( );
System是java.lang里面的一个类
out就是System里面的一个静态数据成员
println是换行输出的方法
根据一个helloword的小功能程序就能知道这么多的东西了
对象和类
问题1:什么是类,什么是对象
类是一个模块,而对象是类的实例,怎么去理解呢:
类 对象
动物--------小猫咪
动物--------小勾勾
动物-------小鸭鸭
可以看出类是一个很大的范围,而对象就是一个具体的东西
问题2:面向对象(OOP)的特征
继承、封装、多态、抽象
简单理解:
继承:子类可以继承父类拥有它的功能
我【英俊潇洒帅气】 ------生下-----------儿子【英俊潇洒帅气 并且聪明 】 那聪明就是子类拥有的功能
封装:无需知道方法具体代码,只要知道它的方法名就能使用
洗衣机 【内部有很多的线路、电路板这呀那丫的】------不需要知道内部------------只需要知道它可以洗衣服
多态:在同一个父类的情况下,不同子类的相同方法,有不同的功能
人类 -----男生-----------男生讲话粗犷
人类------女生-----------女生讲话细腻
抽象:我们在定义一个类的时候,实际上就是把一类事物的公有的属性和行为提取出来,形成一个物理模型,这种研究问题的方法称为抽象。
杯子、碗、水壶
都能用来喝水,那就将他们的共性提取出来,然后用来重复的代码使用
一切皆为对象
public class AAA{
public static void main(String[] args) {
Person 张三 = new Person("张三",15); //这个部分叫做实例对象
Person 李四 = new Person("李四",56);
张三.synopsis(); //这部分是对象调用方法
李四.synopsis();
}
}
//关键字class创建类
class Person {
//属性:代表创建出来的对象有什么状态:名字、年龄、颜色这些
private String name;
private Integer age;
//=========get和set方法=============
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
//=============================
public Person(String name, Integer age) { //构造方法
this.name = name;
this.age = age;
}
public void synopsis() { //方法
System.out.println("我是"+name+"今年"+age+"岁");
}
public static void thisStatic(){ //这是类方法
System.out.println("通过类就能使用我啦~~~");
}
}
代码中提及到的:实例、get和set方法、类方法、构造方法等等
什么是方法
xxx()的就是一个方法的调用格式。
上面的代码中,我一直在提及方法,什么get和set方法呀、什么静态方法呀、构造方法,那到底什么是方法呢?
方法是一个类的行为,它可以让对象有什么功能,例如说人类它是一个类【class】, 人类都是有年龄和名字的 【属性】,它们有共同的行为例如,说话、学习、【方法】
所以说方法就是这个类的行为【这就表明方法是在类里面的】 代码实现:
class person{ //这个是类
public void chang(){ //这个就是方法
System.out.println("我喜欢唱歌");
}
}
方法的一般是通过创建对象来使用的 Person person = new Person() 这样person.chang()【对象名.方法名()】就能使用方法啦
什么是构造方法
Person person = new Person() 你可能会想到这个Person() 这个不是一个方法吗?
没错,这个person()其实也是一个方法,每个类都有一个默认的无参构造方法,方法的名称就是和类名相同
提及一下:方法名和它的形参相同的叫做重写,方法名相同但是形参不同的叫做重载
一个类看似什么都没有
class Person{
}
==========================
其实它里面有个"看不见"的方法,这个方法就叫做无参构造,只要这个类被实例了,那么他这个无参构造默认就会被调用
class Person{
public Person() {
System.out.println("有人把我实例啦~");
}
}
什么是有参构造
有参构造是自己创建出来的一种构造方法,它可以在创建对象的时候就能给这个对象初始化
Person person = new Person("张三") ;
class Person{ public Person(String name) { System.out.println("有人把我实例啦~"+"我叫做"+name); } }
当这个对象被创建的时候,name这个属性的内容,就会通过构造方法来到类里面了,我们可以增加一个属性来存储这个变量,那之后那个属性就是那个变量的内容了
class Person{
//属性
String name; //存储构造方法传入的数据内容
//方法 public Person(String name) {
this.name=name; System.out.println("有人把我实例啦~"+"我叫做"+name); } }
那么这个String name就是张三了
什么是this
看到刚刚上面代码中有一个this.xxx,那么这个this又是什么呢?
this中文翻译就是:“这个”,简单理解就是 this.name就是我这个Person类中的name属性,独属于我这个person类的name属性。
public Person(String name) {
this.name=name; System.out.println("有人把我实例啦~"+"我叫做"+name); }
这个Person类中name属性 = 传入的形参 name的内容
提及一下什么是super
还有一个和this差不多super,它是指用方法或是属性来自父类
一个对象有什么内容
一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。
数据结构、变量、类、对象【实例】、属性、方法、语句结构【条件分支】
- 对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
- 类:类是一个模板,它描述一类对象的行为和状态。
- 方法:方法就是行为,一个类可以有很多方法。逻辑运算、数据修改以及所有动作都是在方法中完成的。
- 实例变量:每个对象都有独特的实例变量,对象的状态由这些实例变量的值决定。
运算符
- 算术运算符、关系运算符、位运算符、逻辑运算符、赋值运算符、其他运算符
算数运算符
算数运算符顾名思义,就是数学上使用的运算符号,即:加、减、乘、除、取余、自增、自减
操作符 | 描述 | 例子 |
---|---|---|
+ | 加法 - 相加运算符两侧的值 | A + B 等于 30 |
- | 减法 - 左操作数减去右操作数 | A – B 等于 -10 |
* | 乘法 - 相乘操作符两侧的值 | A * B等于200 |
/ | 除法 - 左操作数除以右操作数 | B / A等于2 |
% | 取余 - 左操作数除以右操作数的余数 | B%A等于0 |
++ | 自增: 操作数的值增加1 | B++ 或 ++B 等于 21 |
-- | 自减: 操作数的值减少1 | B-- 或 --B 等于 19 |
自增的话分为:i++ 和 ++i 两种,区别就是:i++就是先运算了再加1,++i就是先加了1再运算,
关系运算符(用于条件判断)
配合条件分支使用
下表为Java支持的关系运算符
表格中的实例整数变量A的值为10,变量B的值为20:
运算符 | 描述 | 例子 |
---|---|---|
== | 检查如果两个操作数的值是否相等,如果相等则条件为真。 | (A == B)为假。 |
!= | 检查如果两个操作数的值是否相等,如果值不相等则条件为真。 | (A != B) 为真。 |
> | 检查左操作数的值是否大于右操作数的值,如果是那么条件为真。 | (A> B)为假。 |
< | 检查左操作数的值是否小于右操作数的值,如果是那么条件为真。 | (A <B)为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是那么条件为真。 | (A> = B)为假。 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是那么条件为真。 | (A <= B)为真。 |
位运算符(用到较少)
Java定义了位运算符,应用于整数类型(int),长整型(long),短整型(short),字符型(char),和字节型(byte)等类型。
位运算符作用在所有的位上,并且按位运算。假设a = 60,b = 13;它们的二进制格式表示将如下:
A =00111100 B =00001101----------------- A&B =00001100 A | B =00111101 A ^ B =00110001~A=11000011
下表列出了位运算符的基本运算,假设整数变量 A 的值为 60 和变量 B 的值为 13:
操作符 | 描述 | 例子 |
---|---|---|
& | 如果相对应位都是1,则结果为1,否则为0 | (A&B),得到12,即0000 1100 |
| | 如果相对应位都是 0,则结果为 0,否则为 1 | (A | B)得到61,即 0011 1101 |
^ | 如果相对应位值相同,则结果为0,否则为1 | (A ^ B)得到49,即 0011 0001 |
〜 | 按位取反运算符翻转操作数的每一位,即0变成1,1变成0。 | (〜A)得到-61,即1100 0011 |
<< | 按位左移运算符。左操作数按位左移右操作数指定的位数。 | A << 2得到240,即 1111 0000 |
>> | 按位右移运算符。左操作数按位右移右操作数指定的位数。 | A >> 2得到15即 1111 |
>>> | 按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。 | A>>>2得到15即0000 1111 |
逻辑运算符(配合关系运算符使用)
下表列出了逻辑运算符的基本运算,假设布尔变量A为真,变量B为假
操作符 | 描述 | 例子 |
---|---|---|
&& | 称为逻辑与运算符。当且仅当两个操作数都为真,条件才为真。 | (A && B)为假。 |
| | | 称为逻辑或操作符。如果任何两个操作数任何一个为真,条件为真。 | (A | | B)为真。 |
! | 称为逻辑非运算符。用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符将得到false。 | !(A && B)为真。 |
位运算符
Java定义了位运算符,应用于整数类型(int),长整型(long),短整型(short),字符型(char),和字节型(byte)等类型。
位运算符作用在所有的位上,并且按位运算。假设a = 60,b = 13;它们的二进制格式表示将如下:
A =00111100 B =00001101----------------- A&B =00001100 A | B =00111101 A ^ B =00110001~A=11000011
下表列出了位运算符的基本运算,假设整数变量 A 的值为 60 和变量 B 的值为 13:
操作符 | 描述 | 例子 |
---|---|---|
& | 如果相对应位都是1,则结果为1,否则为0 | (A&B),得到12,即0000 1100 |
| | 如果相对应位都是 0,则结果为 0,否则为 1 | (A | B)得到61,即 0011 1101 |
^ | 如果相对应位值相同,则结果为0,否则为1 | (A ^ B)得到49,即 0011 0001 |
〜 | 按位取反运算符翻转操作数的每一位,即0变成1,1变成0。 | (〜A)得到-61,即1100 0011 |
<< | 按位左移运算符。左操作数按位左移右操作数指定的位数。 | A << 2得到240,即 1111 0000 |
>> | 按位右移运算符。左操作数按位右移右操作数指定的位数。 | A >> 2得到15即 1111 |
>>> | 按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。 | A>>>2得到15即0000 1111 |
赋值运算符
操作符 | 描述 | 例子 |
---|---|---|
= | 简单的赋值运算符,将右操作数的值赋给左侧操作数 | C = A + B将把A + B得到的值赋给C |
+ = | 加和赋值操作符,它把左操作数和右操作数相加赋值给左操作数 | C + = A等价于C = C + A |
- = | 减和赋值操作符,它把左操作数和右操作数相减赋值给左操作数 | C - = A等价于C = C - A |
* = | 乘和赋值操作符,它把左操作数和右操作数相乘赋值给左操作数 | C * = A等价于C = C * A |
/ = | 除和赋值操作符,它把左操作数和右操作数相除赋值给左操作数 | C / = A,C 与 A 同类型时等价于 C = C / A |
(%)= | 取模和赋值操作符,它把左操作数和右操作数取模后赋值给左操作数 | C%= A等价于C = C%A |
<< = | 左移位赋值运算符 | C << = 2等价于C = C << 2 |
>> = | 右移位赋值运算符 | C >> = 2等价于C = C >> 2 |
&= | 按位与赋值运算符 | C&= 2等价于C = C&2 |
^ = | 按位异或赋值操作符 | C ^ = 2等价于C = C ^ 2 |
| = | 按位或赋值操作符 | C | = 2等价于C = C | 2 |
三元运算符(?:)
使用方式: 1>2?"对的":"错的",很明显输出"错的"【左对,右错】
instanceof 运算符
该运算符用于操作对象实例,检查该对象是否是一个特定类型(整形还是什么其他类型)
String name = "我是字符";
boolean result = name instanceof String; // 由于 name 是 String 类型,所以返回真
格式:object 变量名 = 传入的类型 instanceof 判断的类型
运算符的优先级
这个就不用去详细的了解,使用括号包起来可以将优先级提升至最大 ( )
结构体
一般的顺序结构只能被执行一次:如if 、else if、 switch case
如果想要多次使用顺序结构就要使用到循环结构体、for、while、do....while
if判断(重要)
if无法就是判断对于错,对就进入、错就跳过
if(1>2){ system.out.print("我进来") }
这显然是错误的,所以根本就不会进入{}里的语句
if(1<2){
system.out.print("我进来")
}
这显然是正确的,所以会进入{}里的语句,输出"我进来了"
else if
为什么有else if,一直写if不也能完成功能嘛
if:如果有多个if,当条件满足了第一个,它不会停下来的,它会接着判断第二个if是否满足条件、第三个条件.....第n个条件 【无脑愣头青,会占用很多内存空间,影响性能】
else if :如果有多个if 当满足了第一个条件,它就会停下来,不在往下判断了【必须要配合if才能使用】【有智青年,减少内存的占用】
当条件满足就能停下来
int a=2;
if(a<1){ system.out.print("我进来1") }else if(a<=2)
{
system.out.print("我进来2")
}else if(a<3)
{
system.out.print("我进来3")
}
很明显2和3都满足,但是它只进入2
else
else可以认为是其他的,当不满足if的条件就会全部交给else来执行
if (1==2){ System.out.println("进入1"); }else{ System.out.println("条件不满足就会来到这里"); }
只要条件不满足就会来到else
for【重要】
你也不想一直写if来判断条件吧,这时候就可以使用for来完成循环的功能啦
结构:for( 数据类型 变量名; 条件; 更新 )
for (int i = 0; i < 5; i++) { if (i==3){ System.out.println("在循环第三次的时候我进来了"); } }