编程软件:IDEA
快捷键一: psvm或main —— 用来快速写一个main函数
快捷键二: sout —— 用来快速写一个println函数
快捷键三: fori —— 用来快速写一个for循环
快捷键四: Ctrl+Shift+/ —— 用来快速进行块注释
快捷键五: Ctrl+Shift+/ —— 用来快速取消块注释(与快速进行块注释的按键相同)
快捷键六: Ctrl+/ —— 用来快速进行行注释 例如:在代码中点击某一行,然后按Ctrl+/,就可以对这一行进行注释。
快捷键七: Ctrl+/ —— 用来快速取消行注释(与快速进行行注释的按键相同)
被java语言赋予了特殊含义,用作专门用途的字符串
保留字:现在java尚未使用,但以后版本可能会作为关键字使用。自己使用时应避免使用。
凡是可以自己命名的地方都叫标识符。例如:包名,类名,方法等。
注意: 1.有26个英文字母大小写,0-9,_或$组成。
2.不能以数字开头。
3.不可以使用关键字和保留字,但能包含关键字和保留字。
4.严格区分大小写。
5.标识符不能包含空格。
java中的名称命名规范
1.包名:多单词组成时所有字母都小写:xxxyyyzzz
2.类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz
3.变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz
4.常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ
是在程序中的不会变化的数据。
内存中的一个储存区域,该区域的数据可以在同一类型范围内不断变化,变量是程序中最基本的存储单元,包含变量类型、变量名和存储的值
作用:方便于运算。因为有些数据不确定。所以确定该数据的名词和存储空间。
特点:变量空间可以重复使用。
在方法体外,类体内声明的变量称为成员变量。
在方法体内部声明的变量称为局部变量。
变量的作用域和生存期:
变量的作用域:
作用域从变量定义的位置开始,到该变量所在的那对大括号结束;
生命周期:
变量从定义的位置开始就在内存中活了;
变量到达它所在的作用域的时候就在内存中消失了;
1.基本数据类型:byte、short、int、long、float、double、char、boolean
2.引用数据类型: 数组、类、接口。
数据类型及类型间的转换:
级别从低到高为:byte,char,short(这三个平级)——>int——>float——>long——>double
自动类型转换: 当容量(数值范围)小的数据类型与容量大的数据类型的变量做运算时,运算结果就自动提升为容量大的数据类型
比如:short + int → int,int + long → long,long + float → float,float + double → double
强制类型转换: 强制类型转换是自动类型提升运算的逆运算。强制类型转换的实现需要使用强转符:()
1.算术运算符
%:任何整数模2不是0就是1,所以只要改变被模数就可以实现开关运算。
+:连接符。
++,——
2.赋值运算符
= += —= *= /= %=
3.比较运算符
特点:该运算符的特点是:运算完的结果,要么是true,要么是false。
4.逻辑运算符
& | ^ ! && ||
逻辑运算符除了 ! 外都是用于连接两个boolean类型表达式。
&: 只有两边都为true结果是true。否则就是false。
|:只要两边都为false结果是false,否则就是true
^:异或:和或有点不一样。
两边结果一样,就为false。
两边结果不一样,就为true.
& 和 &&区别: & :无论左边结果是什么,右边都参与运算。
&&:短路与,如果左边为false,那么右边不参数与运算。
| 和|| 区别: |:两边都运算。
||:短路或,如果左边为true,那么右边不参与运算。
5.位运算符:用于操作二进制位的运算符
& | ^
<< >> >>>(无符号右移)
6.三元运算符
语法形式:布尔表达式 ? 表达式1:表达式2
布尔表达式为true,运算结果为表达式1。反之,结果为表达式2。
输入: Scanner input = new Scanner(System.in);
nextInt(), nextDouble(), next(), nextLine()
输出: system.out.println() 有换行
分支结构: if switch---break
1.if else语句:
嵌套else就近原则
if ();后面不能加 ;
2.switch 语句:
case:类型相同,且为常数
break:跳出循环
default 可选项,无符合条件case时执行
循环结构: for while do while---- continue break
foreach语句是for语句特殊情况下的增强版本,简化了编程提高了代码的可读性和安全性不用怕数组越界。
相对老的for语句来说是个很好的补充,提倡能用foreach的地方就不要再用for了。
在用到对集合或者数组索引的情况下foreach显得力不从心这个时候是用for语句的时候了, foreach一般结合泛型使用
for(元素类型type 元素变量value :遍历对象obj){
引用x的java语句`
}
数组是可以存储同一种数据类型多个元素的集合,也可以看成是一个容器
数组既可以存储基本数据类型,也可以存储引用数据类型
格式:elementType[] arrayRefVar = new elementType[arraySize]
静态初始化:给出初始化值,由系统决定长度
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,...};
动态初始化:只指定长度,由系统决定初始化值
数据类型[] 数组名 = new 数据类型[数组的长度];
利用循环遍历数组
//for:
for (int i = 0; i < args.length; i++) {
System.out.println(args.length);
}
//foreach:
for(elementType element:arrayRefVar){
System.out.println(e)
}
对于基本数据类型参数,传递的是实参的值
对于数组类型参数,传递的是数组的引用
多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。
二维数组:数据类型[] 数组名 = new 数据类型[数组的长度i][数组的长度j];
public static void araryDeclareCreateInitializer() {
// Java 中数组既不是对象也不是基本数据类型。而是一种储存数据的方式
double[] myList1; // 声明数组 myList1,不分配内存空间,只是创建引用位置:仅只是定义一个变量
// int myList[]; // 兼容c
myList1 = new double[10]; // ---------创建数组
double[] myList2 = new double[20]; // --------声明+创建
// 声明数组变量myList2,创建20个元素构成数组,将数组引用赋值给myList2
// 相当于上面两句
myList1[0] = 1.1; // --------数组初始化
myList1[1] = 1.2;
System.out.println(myList1[0] + "---");
double[] myList3 = {1.1, 1.2, 1.3, 2.1}; // ------- 声明,创建,初识化在一条语句
}
方法是语句的集合,它们在一起执行一个功能,本意是功能快,就是实现某个功能的语句块的集合
方法是解决一类问题的步骤的有序组合
方法包含于类或对象中
方法在程序中被创建,在其他地方被引用
方法包含一个方法头和一个方法体,下面是一个方法的所有部分:
修饰符:可选的,告诉编译器如何调用该方法
返回值类型:方法可能会有返回值。returnValueType是返回值类型
方法名:实际名称,和参数表共同构成方法签名
参数类型:参数像是一个占位符。当方法被调用时,传递值给参数,这个值称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数
形参:在方法被调用时用于接收外界输入的数据
实参:调用方法时实际传给方法的数据
方法体:方法体包含具体的语句,定义该方法的功能
修饰符 返回值类型 方法名(参数类型 参数名){
//例public static returnValueType methodName(list of para)
...
方法体
...
return 返回值;
}
构成重载:
方法名相同
参数个数不同
参数类型不同
参数顺序不同
不构成重载:编译错误
只有返回值不同 public int add(int n1,int n2) public double add(int n1,int n2)
只有参数名称不同 public int add(int n1,int n2) public int add(int n2,int n1)
public static void main(String[] args) {
max(1,2); //方法调用
max(1,2,3);
}
public static int max(int a,int b){ //方法定义
if (a>b) return a;
else return b;
}
public static int max(int a,int b,int c){ //方法重载
if (a>b&&a>c) return a;
else if(b>a&&b>c) return b;
else return c;
}
typeName...parameterName(类型名...参数名) 参数个数可变
值传递,变量值不改变 (注:参数是数组时,会改变数组值)
将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互,是面向对象三大特征之一
可以将一个类的定义放在里另一个类的内部,这就是内部类。内部类分为四种:成员内部类、静态内部类、局部(方法)内部类、匿名内部类。
内部类访问特点:
内部类可以直接访问外部类的成员,包括私有
外部类要访问内部类的成员,必须创建对象
在类的成员位置
可以是任何的访问修饰符。
内部类的内部不能有静态信息。
内部类也是类,继承、重写、重载注意使用,this和super可以任意使用。
外部类要访问内部类信息,必须使用new之后访问。
内部类可以直接使用外部类的任何信息,如果属性或者方法发生冲突,调用外部类.this.属性或者方法。
外界访问时的格式: 外部类名.内部类名 对象名 = 外部类对象.内部类对象
代码示例:
public class Outer {
private int num=10;
public class Inner{ //成员内部类
public void show(){
System.out.println(num);
}
}
//可以使用这种类型,通过内部类的另一方法访问
private class Inner2{
public void show(){
System.out.println(num);
}
}
public void method2(){ //访问私有Inner2类
Inner2 i=new Inner2();
i.show();
}
}}
public class Demo {
public static void main(String[] args) {
Outer.Inner a=new Outer().new Inner(); //第一种方法
a.show();
Outer o=new Outer(); //第二种方法
o.method2();
}
}
内部可以包含任意的信息。
静态内部类的方法只能访问外部类的static关联的信息。
访问内部类的静态信息,直接外部类.内部类.静态信息就可以了。
静态内部类可以独立存在,不依赖于其他外围类。
格式: 外部类.内部类 引用=new 外部类.内部类()
public class Outer {
private int num=10;
public static class Inner{ //静态内部类
public void InnerShow(){
System.out.println("静态内部类成员方法被调用");
}
public static void InnerShow2(){
System.out.println("静态内部类静态方法被调用");
}
}
}
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
Outer.Inner.InnerShow2(); //访问静态内部类的静态方法
Outer.Inner o=new Outer.Inner(); //访问静态内部类的成员方法
o.InnerShow();
}
}
在类的局部位置
在方法中定义的类,所以外界是无法直接使用,需要在方法内部创建对象并使用
该类可以直接访问外部类的任何信息,也可以访问方法内的局部变量和参数
类前不能有访问修饰符。
无法创造静态信息。
代码示例:
public class Outer {
private int num=10;
public void method(){
int num2=20;
class Inner{ //局部内部类
public void show(){
System.out.println(num);
System.out.println(num2);
}
}
Inner i=new Inner(); //需要在方法内部创建对象并使用
i.show();
}
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
Outer o=new Outer();
o.method();
}
}
/*
输出结果:
10
20
*/
前提:存在一个类或者接口,这里的类可以是具体类也可以是抽象类
本质:是一个继承了该类或者实现了该接口的子类匿名对象
匿名内部类没有访问修饰符
匿名内部类没有构造方法
使用匿名内部类时,这个new之后的类首先是要存在的,其次我们要重写new后的类的某个或某些方法
匿名内部类访问方法参数时也有和局部内部类同样的限制
格式: new 类名或者接口名(){
重写方法
}; //注意结尾要分号
代码示例:
public interface Inner2 { //接口
void show();
}
public class Outer {
private int num=10;
public void method(){
int num2=20;
new Inner2(){ //匿名内部类 第一种输出
@Override
public void show() {
System.out.println("匿名内部类");
}
}.show();
new Inner2(){ //两次输出
@Override
public void show() {
System.out.println("匿名内部类");
}
}.show();
Inner2 in= new Inner2(){ //第二种输出
@Override
public void show() {
System.out.println("匿名内部类");
}
};
in.show();
}
}
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
Outer o=new Outer();
o.method();
}
}
继承是面向对象三大特征(封装、继承、多态)之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模
extands的意思是“扩展”, 子类是父类的扩展
java中类只有单继承,没有多继承
继承是类和类之间的一种关系,类和类的之间的关系还有依赖、组合、聚合等
继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键=字extends来表示
子类和父类之间,从有意义上讲有“is a”的关系
super关键字:
super调用父类的构造方法,必须在构造方法的第一个
super必须只能出现在子类的方法的或者构造方法中
super和this 不能同时调用构造方法
VS this:
代表的对象不同:
this:本身调用者
super:代表父类对象的应用
前提不同:
this:没有继承可以使用
super:只能在继承条件下才可以使用
构造方法不同:
this():本类的构造
super():父类的构造
好处:提高了代码的复用性(多个类相同的成员可以放到同一个类中)
提高了代码的维护性(如果方法的代码需要修改,修改一处即可)
弊端:继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类实现也不得不跟着变化,削弱了
子类的独立性
在子类方法中访问一个变量:
先在子类局部范围找
再在子类成员范围找
然后在父类成员范围找
如果都没有就报错
子类中所有的构造方法默认都会访问父类中无参的构造方法:
因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化
每一个子类构造方法的第一条语句默认都是super()
如果父类中没有无参构造方法,只有带参构造方法:
通过使用super关键字去显示的调用父类的带参构造方法
在父类中自己提供一个无参构造方法
通过子类对象访问一个方法
子类成员范围找
父类成员范围找
如果都没有就报错
子类中出现了和父类一模一样的方法声明。
应用:当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。
代码示例
public class Fu {
private int age;
public Fu() { //父类无参构造方法
System.out.println("fu中无参构造方法被调用");
}
public Fu(int age) { //父类带参构造方法
this.age = age;
System.out.println("fu中带参构造方法被调用");
}
public int getAge() { //getAge 成员方法
return age; //便于外界访问age
}
public void setAge(int age) { //setAge 成员方法
this.age = age; //this调用本身的私有成员变量
}
public void show(){ //show方法
System.out.println("fu中show方法被调用");
}
}
public class Zi extends Fu{
public Zi() { //子类无参构造方法
//super(); 默认调用
System.out.println("zi中无参构造方法被调用");
}
public Zi(int age) { //子类带参构造方法
super(age); //调用父类带参构造方法
}
@Override
public void show() { //重写父类的show方法
super.show();
}
}
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
Zi z1=new Zi(); //创建子类对象,调用子类无参构造方法,由于继承关系,会先调用父类无参构造方法
System.out.println("--------");
z1.setAge(20);
System.out.println(z1.getAge());
System.out.println("--------");
Zi z2=new Zi(19); //创建子类对象,使用子类带参构造方法
System.out.println(z2.getAge());
System.out.println("--------");
z2.show();
/*
输出结果:
fu中无参构造方法被调用
zi中无参构造方法被调用
--------
20
--------
fu中带参构造方法被调用
19
--------
fu中show方法被调用
*/
}
}
static修饰的成员变量和方法,从属于类
普通变量和方法从属于对象
静态只能用静态
静态方法优点:不需要new对象,直接采用类名调用,极其方便
声明变量为实例或静态:如果这个类型的所有对象的某个属性值都是一样的,不建议定义为实例变量,浪费内存空间。建议定义为类级别特征,即静态变量,在方法区中只保留一份,节省内存开销。
定义方法为实例方法或静态方法:1.如果该方法必须由对象去触发,则定义为实例方法 2.在方法体中,直接访问了实例变量,则一定是实例方法 在开发中,工具类中的方法一般是定义为静态的
三角函数
sin(弧度) 返回正弦函数值
cos(弧度) 返回余弦函数值
tan(弧度) 返回正切函数值
toDegrees(弧度) 弧度转化为度
toRadians(度) 度转化为弧度
asin() 返回反正弦函数值
acos() 返回反余弦函数值
atan() 返回反正切函数值
指数函数
exp(x) 返回e的x次方
log(x) 返回x的自然底数
log10(x) 返回x的以10为底的对数
pow(a,b) 返回a的b次方
sqrt(x) 返回x的平方根(x>=0)
取整方法
ceil() 向上取整
floor() 向下取整
rint() 取整最接近的整数
round() 四舍五入
min,max,abs,random方法
min() 最小值
max() 最大值
abs() 绝对值
random() 随机数(0<=random<1)
isDigit() 判断是否为数字
isLetter() 判断是否为字母
isDigitorLetter() 判断是否为数字或字母
isUpperCase() 判断是否为大写字母
isLowerCase() 判断是否为小写字母
toUpperCase() 转为大写
toLowerCase() 转为小写
length() 返回字符长度
charAt() 返回指定位置字符
concat(s1)) 两字符串拼接
toLowerCase()) 全部小写
toUpperCase()) 全部大写
trim() 去除两边空格
equals() 判断是否相等
equalsIgnoreCase() 判断是否相等(不区分大小写)
subString() 返回两下标间的字符串
indexOf() 获取字符串的下标
构造方法:
无参构造 public Date():分配一个Date对象,并初始化,以便它代表它被分配的时间,精确到毫秒
带参构造 public Date(long date):分配一个Date对象,并将其初始化为表示 从标准基准时间起 指定的毫秒数
public static void main(String[] args) {
Date d1=new Date();
System.out.println(d1); //返回当前时间
long l=1000*60*60;
Date d2=new Date(l);
System.out.println(d2);
}
常用方法:
public long getTime(), 获取的是日期对象从1970年1月1日 00:00:00到现在的毫秒值
public void setTime(), 设置时间看,给的是毫秒值
public class DateDemo {
public static void main(String[] args) {
Date d=new Date(); //创建日期对象
System.out.println(d.getTime());
System.out.println(d.getTime()*1.0/1000/60/60/24/365+"年");
long time=System.currentTimeMillis();
d.setTime(time);
System.out.println(d);
long time2=1000*60*60;
d.setTime(time2);
System.out.println(d);
}}
SimpleDateFormat类: 简单日期格式
构造方法:
public SimpleDateFormat(): 构造一个SimpleDateFormat,使用默认模式和日期格式
public SimpleDateFormat(String pattern): 构造一个SimpleDateFormat使用给定的模式和默认的日期格式
年:y 月:M 日:d 时:H 分:m 秒:s
格式化: 从Date到String
public final String format(Date date): 将日期格式化为日期/时间字符串
解析: 从String到Date
public Date Parse(String source): 从给定字符串的开始解析文本以生成日期
代码示例:
public static void main(String[] args) throws ParseException {
//格式化: 从Date到String
Date d=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String s=sdf.format(d);
System.out.println(s);
//解析: 从String到Date
String ss="2022-09-26 22:00:54";
SimpleDateFormat sdf2=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //注意要对应 否则报错
Date dd=sdf2.parse(ss);
System.out.println(dd);
}
包装类与基本数据类型的区别:
声明方式不同,基本类型不用new创建,封装类需要
存储方式和位置不同,基本类型直接存储变量的值保存在堆栈中,能高效的存取;封装类型需要通过引用指向实例,具体的实例保存在堆中
初始值的不同,封装类型的初始值为null,基本类型的的初始值视具体的类型而定,比如int类型的初始值为0,boolean类型为false;
什么时候用
字段是否允许null值,如果允许null值,则用包装类
用到比如泛型和反射调用函数,就需要用包装类
在使用集合类型时,就一定要使用包装类型,因为容器都是装object的,基本数据类型显然不适用
自动装箱:通过调用包装类的valueOf()方法实现的
Integer i=100; //Integer i=Integer.valueOf(100)
自动拆箱:通过调用包装类的xxxValue()方法实现的,xxx表示对应基本数据类型,如intValue()、doubleValue().
Integer i=100;
int j=i; //int j=i.intValue()
枚举类型隐性地继承自java.lang.Enum,实质上是个类,每个被枚举的成员实质是一个枚举类型的实例,默认是public static final修饰,可以直接用枚举类型名使用它们
建议:
需要定义一组常量时,可以使用枚举类型
尽量不要使用枚举的高级特性,事实上高级特性可以直接使用普通类实现,没必要用枚举,提高复杂性
enum 枚举名{
枚举体(常用列表)
}
//示例
enum Season{
春,夏,秋,冬
}