<>Java - 基础语法一

<>① 基础语法

* JVM(Java Virtual Machine): Java 虚拟机,简称 JVM,是运行所有 Java 程序的假想计算机,是 Java
程序的运行环境,是 Java 最具吸引力的特性之一。我们编写的 Java 程序,都运行在 JVM 之上。
* JRE(Java Runtime Environment):Java 程序的运行环境,包含 JVM 和运行时所需要的核心类库。
* JDK(Java Development Environment):Java 程序开发工具包,包含 JRE 和开发人员使用的工具。

<>方法

格式:
修饰符 返回值类型 方法名(参数列表) { // 代码 return 结果;// 如果返回值类型不为 void }
<>方法重载:多个方法的名称一样,但是参数列表不一样

<>方法重载与以下因素有关:

* 参数个数不同
* 参数类型不同
* 参数的多类型顺序不同
<>方法重载与以下因素无关:

* 与参数的名称无关
* 与方法的返回值类型无关
<>数组:一种容器,可以同时存放多个数据源

<>数组特点:

* 数组是一种引用数据类型
* 数组当中的多个数据,类型必须统一
* 数组的长度在程序运行期间不可改变
<>动态初始化:在创建数组的时候,直接指定数组当中的数据元素个数

格式:数据类型[] 数组名称 = new 数据类型[数组长度]

<>静态初始化:在创建数组的时候,不直接指定数据个数多少,而是直接将具体的数据内容进行指定

标准格式:数据类型[] 数组名称 = new 数据类型[] {元素 1、元素 2、...}
省略格式:数据类型[] 数组名称 = {元素 1、元素 2、...}

<>注意事项

* 静态初始化没有直接指定长度,但是仍然会自动推算得到长度 int[] arrayA = {10, 20, 30};
* 静态初始化标准格式可以拆分成两个步骤 int[] arrayB; arrayB = new int[5];
* 动态初始化也可以拆分成两个步骤 int arrayC; arrayC = new int [] {1, 2, 3 };
* 静态初始化一旦使用省略格式,就不能拆分成为两个步骤了
<>Java 的内存需要划分成为 5 个部分:

* 栈(Srack):存放的都是方法中的局部变量,方法的运行一定在栈中
* 局部变量:方法的参数,或者是方法{} 内部的变量。
* 作用域:一旦超出作用域,立刻从栈内存当中消失。
* 堆(Heap):凡是 new 出来的东西,都在堆当中
* 堆内存里面的东西都有一个地址值:16 进制
* 堆内存里面的数据,都有默认值
* 方法区(Method Area):存储 .class 相关信息,包含方法的信息。
* 本地方法栈(Native Method Stack):与操作系统相关
* 寄存器(pc Register):与 CPU 相关
<>② 面向对象

<>局部变量和成员变量

* 定义的位置不同
* 局部变量:在方法内部
* 成员变量:在方法外部,直接写在类中
* 作用范围不同
* 局部变量:只有在方法中才可以使用,出了方法就不能用
* 成员变量:整个类全都可以通用
* 默认值不同
* 局部变量:没有默认值,如果想使用,必须手动进行赋值
* 成员变量:如果没有赋值,会有默认值,规则和数组一样
* 内存位置不一样
* 局部变量:位于栈内存
* 成员变量:位于堆内存
* 生命周期不一样
* 局部变量:随方法进栈而诞生,随着方法出栈而消失
* 成员变量:随着对象创建而诞生,随着对象被垃圾回收而消失
<>面向对象三大特性:封装、继承、多态

封装性在 Java 体现:

* 方法就是封装
* Private 关键字也是封装
对于基本数据类型当中的 boolean 值,Getter 方法一定要写成 isXxx 的形式,而 setXxx 规则不变

<>构造方法

构造方法是专门用来创建对象的方法,当我们通过关键字 new 来创建对象时,其实就是在调用构造方法

<>格式:
public 类名称(参数类型 参数名称) { 方法体 }
<>构造方法使用注意事项:

* 构造方法的名称必须和所在的类名称完全一样,就连大小写也要一样
* 构造方法不要写返回值类型,连 Void 都不写
* 构造方法不能 return 一个具体返回值
* 如果没有编写任何构造方法,编译器会默认生成一个构造方法,无参数、无方法体
* 一旦编写了至少一个构造方法,编译器便不再自动生成
<>标准的类

* 所有的成员变量都要用 private 关键字修饰
* 为每一个成员变量编写一对儿 Getter/Setter 方法
* 编写一个无参数的构造方法
* 编写一个全参数的构造方法
<>③ 常用 API

<>Random

用于生成随机数
public int nextInt(int n) 返回一个 [0,n) 之间的随机数。

<>ArrayList

数组的长度不可以发生变化,ArrayList 集合的长度是可以随意变化的。
如果希望向 ArrayList 当中存储基本类型数据,必须使用基本类型对应的“包装类”

基本类型 包装类(引用类型)
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
<>String

程序中所有双引号字符串,都是 String 类的对象

<>特点

* 字符串的内容永不改变
* 正是因为字符串不可改变,所以字符串是可以共享使用的
* 字符串效果上相当于是 char[] 字符数组,底层原理是 byte[] 字节数组
字符串常量池,在堆中开辟的一块空间。 使用 “” 直接创建的字符串都存放在字符串常量池中。

* 对于引用类型来说,“==” 进行的是地址值的比较,基本数据类型是对值的比较;
* 双引号直接创建的字符串在常量池中,new 的不在池中。
如果需要对字符串的内容进行比较,可以使用如下方法:
public boolean equals(Object obj); // 严格区分大小写 public boolean
equalsIgnoreCase(Object obj); // 忽略大小写
split 方法的参数其实是一个正则表达式,如果要按照英文 . 进行切分,必须写 “\\.” (两个反斜杠)

<>Static 关键字

用来修饰成员变量和成员方法,被修饰的成员属于类的,而不是单单是属于某个对象的。

* 当 static 修饰成员变量,该变量称为类变量,该类的每个对象都共享同一个类变量的值。
格式: static 数据类型 变量名;
* 当 static 修饰成员方法时,该方法称为类方法。
静态代码块:定义在成员位置,使用 static 修饰的代码块 {}

* 位置:类中方法之外
* 执行:随着类的加载而执行且只执行一次,优先于 main 方法和构造方法的执行。
* 作用:类类变量进行初始化赋值。
格式:
public class className { static { /// 执行语句 } }
<>Arrays

java.util.Arrays 是一个与数组相关的工具类,里面提供了大量的静态方法,用来实现数组常见操作。
toString(数组) 将参数数组变成字符串
sort(数组) 按照默认升序对数组的元素进行排序:注意 如果数组内是自定义类型,那么这个自定义类需要有 Comparable 或者 Comparator
接口的支持。

<>Math

abs(double num) 绝对值
ceil(double num) 向上取整
floor(double num) 向下取整
round(double num) 四舍五入
Math.PI 圆周率

<>④ 继承

<>继承

子类继承父类的属性和行为,使得子类对象具有父类相同的属性、相同的行为,子类可以直接访问父类中的非私有的属性和行为。
优点:
1、提高代码的复用性
2、类与类之间产生了关系,是多态的前提。

子父类中出现了同名的成员变量时,在子类中需要访问父类中非私有变量时,需要使用 super 关键字修饰父类成员变量。

如果子父类中出现了同名的成员方法,这是的访问是一种特殊情况-称之为方法重写

Java 中指支持单继承,不支持多继承。

<>抽象类

父类中的方法,被他的子类们重写,子类各自的实现都不尽相同,那么父类的方法声明和方法主体,只有声明还有意义,而方法主体则没有存在的意义了,我们把没有方法主体的方法称为抽象方法。包含抽象方法的类就是抽象类。

<>抽象方法

抽象方法,方法前加 abstract 关键字,去掉关键字,直接分号结束。
定义格式:
修饰符 abstract 返回值类型 方法名(参数列表);
<>抽象类

抽象类:抽象方法所在的类,必须是抽象类才行,在 class 之前写上 abstract 即可。抽象类可以定义正常方法。
定义格式:
abstract class 类名字 { ///xxx }
注意:

* 抽象类不能实例化,必须用子类继承抽象父类,子类必须覆盖重写抽象类的所有抽象方法。
* 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。
* 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
* 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错,除非子类也是抽象类。
<>⑤ 接口

接口是 Java
中的一种引用类型,是方法的集合,如果类的内部封装了成员变量,构造方法和成员方法,那么接口的内部主要就是封装了方法。接口不是类,是一种引用数据类型,其他的引用数据类型还包括:数组、类。
接口可包含五部分:常量、抽象方法、默认方法、静态方法、私有方法
定义格式:
public interface 接口名称 { // 抽象方法,继承类必须全部实现 // 默认方法,default
修饰符修饰,可以继承可以重写,必须通过实现类来调用 // 静态方法,只能通过接口名调用,不可通过实现类名或者实现类对象调用 //
私有方法,私有成员方法只有默认方法可以调用、私有静态方法只有默认方法和静态方法可以调用 }
接口使用步骤:

* 接口不能直接使用,必须有一个“实现类”来“实现”该接口;格式:public class 实现类名称 implement 接口名称
* 接口的实现类必须覆盖重写接口中所有的抽象方法。
* 创建实现类的对象,进行使用
注意事项:

* 如果实现类并没有覆盖重写接口的所有抽象方法,那么这个实现类自己就必须是抽象类。
* 接口没有静态代码块或者构造方法
* 一个类的直接父类是唯一的,但是一个类可以用时实现多个接口。格式:public class 类名称 implements 接口 A, 接口 B {}
* 多个接口存在相同名称抽象方法,实现类只需覆盖重写一次即可。
* 如果实现类没有覆盖重写所有接口中定义的所有抽象方法,那么实现类就必须是一个抽象类。
* 如果多个接口中存在相同名称的默认方法,那么实现类一定要对冲突的默认方法进行覆盖重写。
* 一个类如果直接父类中的方法和接口当中的默认方法产生了冲突,优先用父类中的方法。(Java 继承优先级高于接口)
<>接口中的方法默认是抽象方法

格式: public abstract 返回值类型 方法名称(参数列表);
实现类必须覆盖重写接口所有抽象方法,除非实现类是抽象类。

<>接口中的默认方法

接口中的默认方法可以解决接口升级的问题。
格式:public default 返回值类型 方法名称(参数列表);

<>接口中静态方法

不能用接口实现类的对象来调用接口中的静态方法,应该直接使用接口名称直接调用静态方法。
格式:public static 返回值类型 方法名称(参数列表);

<>接口中的私有方法

抽取公共方法用来解决多个默认方法之间重复代码的问题,但这个共有方法不应该让实现类使用,应该是私有化的。
格式:private default 返回值类型 方法名称(参数列表);、private static 返回值类型 方法名称(参数列表);

<>接口中的“成员变量” 即 “常量”

接口中可以定义“成员变量”,但必须使用 public static final 三个关键字进行修饰(可省略)。从效果上看,这其实就是接口的“常量”。一旦使用
final 关键字,说明不可变
格式:public static final 数据类型 名称 = 数据值;
注意事项:

* 接口中的常量,可以省略 public static final 关键字。含义不变。
* 接口中的常量,必须进行赋值,不能不赋值。
* 建议常量名称大写。多个单词用 _ 分割。
<>接口中的多继承

* 类与类之间是单继承的,直接父类只有一个
* 类与接口之间是多继承的,一个类可以实现多个接口
* 接口与接口之间是多继承的
* 多个父接口中的抽象方法可以重复
* 多个父接口中的默认方法如果重复,必须在子接口进行覆盖重写,并带 default 关键字。
<>接口其他特性

* 接口中,无法定义成员变量,但可以定义常量,其值不可改变,默认使用 public static final 修饰,可以省略、
* 接口中,没有构造方法,不能创建对象
* 接口中,没有静态代码块
<>⑥ 多态

对象具有多个形态
代码中体现多态性,父类引用指向子类对象。格式:父类名称 对象名 = new 子类名称(); 或 接口名称 对象名 = new 实现类名称();

多态访问成员变量的两种方式:

* 直接通过对象名称访问成员变量:看等号左边是谁,优先用谁,没有则向上找。(成员变量无法进行覆盖重写)
* 间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找。
多态访问成员方法:
看 new 的是谁,就优先用谁,没有则向上找。

口诀:
多态访问成员变量:编译看左边,运行也看左边
多态访问成员方法:编译看左边,运行看右边。

多态的好处:无论右边 new 的是哪个子类对象,左边声明的类和调用的方法可以保持一致。

<>对象的向上转型

其实就是多态的写法:父类名称 对象名 = new 子类名称();
含义:右侧创建一个子类对象,把它当做父类看待使用。
注意事项:向上转型一定是安全的。类似于基本数据类型的类型转换 (float -> double)
弊端:一旦向上转型为父类,那么就无法调用子类原本特有的内容。(解决方案-使用向下转型)

<>对象的向下转型

其实是一个还原的动作。格式:子类名称 对象名 = (子类名称)父类对象;
含义:将父类对象,还原为本来的子类对象
注意事项:
必须保证对象创建的时候就是向下转型的类型。

<>instanceof 关键字

返回一个 boolean 值,判断前面的对象能不能当做后面类型的实例。
格式:对象名 instanceof 类名

<>⑦ 其他

<>final 关键字

用于修饰不可改变的内容

<>final 用法

* 修饰类:不能有任何子类,而且一个类如果是 final 的,那么其中所有的成员方法都无法对其进行覆盖重写
* 修饰方法:这个方法不能被覆盖重写,对于类和方法而言,abstract 关键字和 final 关键字不能同时使用,因为矛盾。
*
修饰局部变量:这个变量只能被赋值一次,不能再次被修改。“一次赋值,终生不变”。对于基本数据类型,不可变值得是变量中的数据不可变;对于引用类型,不可变指的是变量中的地址值不可变。
* 修饰成员变量:这个变量只能而且必须被赋值一次,不能再次被修改。而且不再有默认值。
* 由于成员变量具有默认值,所以用了 final 之后必须手动赋值,不会再有默认值。
* 对于 final 的成员变量,要么使用直接赋值,要么使用构造方法赋值,两者取其一。
* 如果使用构造方法对 final 修饰的成员变量赋值,必须保证类中所有重载的构造方法,都最终会对 final 的成员变量进行赋值。
* 被 final 修饰的常量名称,一般有书写规范,所有字母均大写。
<>Java 中的四种权限修饰符

public > protected (专门给不同包子类用的) > (default) > private

public protected (default) private
同一个类(我自己) YES YES YES YES
用一个包(我邻居) YES YES YES NO
不同包子类(我儿子) YES YES NO NO
不同包非子类(陌生人) YES NO NO NO
<>内部类

<>分类:

* 成员内部类
* 局部内部类(包含匿名内部类)
<>成员内部类

格式:
修饰符 class 外部类名称 { 修饰符 class 内部类名称 { xxx } }
内部类可以直接访问外部类的成员,包括私有成员。
外部类要访问内部类的成员,必须建立内部类的对象。
即 : 内用外,随意访问。外用内需要借助内部类对象。

<>如何使用成员内部类

* 间接方式:在外部类的方法中,使用内部类;然后 main 只是调用外部类的方法。
* 直接方式:定义格式:外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();
<>内部类使用外部类的成员变量

如果出现重名现象,使用格式:外部类名称.this.外部类成员变量名
实例:
public class Outer { int num = 10; public class Inner { int num = 20; public
void methodInner() { int num = 30; System.out.println(num); // 局部变量,就近原则 System.
out.println(this.num); // 内部类的成员变量 System.out.println(Outer.this.num); //
外部类的成员变量 } } }
<>局部内部类

如果一个类定义在一个方法内部,那么就是局部内部类。
“局部”:只有当前所属的方法才能使用它,出了这个方法外面就不能用了。

局部内部类如果要访问所在方法的局部变量,那么这个局部变量必须是【有效 final 的】即 用 final 声明的变量或者事实上只赋值一次的变量。
原因:new 出来的对象在堆内存中,局部变量跟着方法走,在栈内存中。方法运行结束立刻出栈,局部变量立即消失。但是 new
出来的对象会在堆中持续存在,直到垃圾回收消失。

<>定义类的权限修饰符

* 外部类:public 或 (default)
* 成员内部类:都可以
* 局部内部类:什么都不能写
<>匿名内部类

如果接口的实现类(或者是父类的子类)只需要使用唯一的一次,那么这种情况下就可以省略掉该类的定义,而改为使用匿名内部类

定义格式:
接口名称 对象名 = new 接口名称() { /// 覆盖重写接口中所有的抽象方法。 }
对格式 “new 接口名称(){…}” 进行解析:

* new 代表创建对象的动作
* 接口名称就是匿名内部类需要实现哪个接口
* {…} 这才是匿名内部类的内容
注意事项:

* 匿名内部类,在【创建对象】的时候只能使用唯一一次,如果希望多次创建对象,那么就必须使用单独定义的实现类。
* 匿名对象,在【调用方法】的时候只能调用唯一一次,如果希望同一个对象调用多次方法,那么必须给对象起个名字。
* 匿名内部类是省略了【实现类/子类名称】,但是匿名对象时省略了【对象名称】,匿名内部类和匿名对象不是一回事!!
<>interface 作为成员变量

使用接口作为成员变量以便随时更换实现方式,这种设计更为灵活,增强了程序的扩展性。
接口作为成员变量时,对他进行复制的操作,实际上是赋给他接口的一个子类实现对象。

接口作为参数数,传递它的子类对象;
接口作为返回值类型是,也是返回它的子类对象。

技术
©2019-2020 Toolsou All rights reserved,
Qt学习2——.pro文件和.h文件介绍LinkedHashMap基本用法&使用实现简单缓存pytorch之ResNet18(对cifar10数据进行分类准确度达到94%)华为Mate 40 Pro+ 5G曝光:徕卡电影镜头、陶瓷机身统计字母个数(java语言实现)JavaScript中的 Call 和 Apply1190 反转每对括号间的子串 leetcode记一次EventBus内存泄露导致的项目问题浅谈uni-app页面传值问题 Chrome OS,对程序员和Windows意味着什么?,互联网营销