java基于java虚拟机(Java Virtual Machine,JVM)和java应用编程接口(Application Programming Interface,API)构成

java的跨平台得益于java虚拟机,只需要编译一次java程序,就可以在不同系统的java虚拟机上运行

java编译成字节流,java虚拟机通过解析这些字节流来做的跨平台,编译完成得到的字节流可以在不同平台的java虚拟机上跑

java分为Java SE、Java EE 和 Java ME。

类的命名:必须是英文开头,后可字母,数字和下划线

一般为大写字母开头

例如:

public class Abc

public是访问修饰符,表示该class为公开,如果没有写pulic,也可以正常编译,但是这个class将不能在命令行中执行

在class内部可以定义方法,例如:

public static void main(String[] args){}

这个例子的方法名为main,返回值为void,表示没有返回值,空

static是一个关键字,同样也是修饰符,表示静态方法

java入口程序必须是静态方法,方法名也必须为main,参数必须为String数组

在方法内部,语句才能执行,每一行程序都必须要以分号结束;

// 单行注释

/*

多行注释

*/

/** *

  • 一样是多行注释 * */

java的变量的类型和JavaScript一样,变量分两种,基本类型变量和引用类型变量 java有8种基础类型,分别是整型(4种),字符型(1种),浮点型(2种),布尔型(1种)

变量必须先定义,后赋值使用,例如:

int a = 1;

定义为int整数类型,名称为a,初始值为1

变量的特点就是可以重新赋值

int i = 1; // 定义int类型,名称为i,赋值为1

i = 100; // 重新赋值为100

int x = i; // 变量x的值为i,因为i的值为100,所以x的值为i

整型

整型类型:int,byte,short,long

整型类型的数就是整数,整数默认为int,在数值后加上L就代表为long,例如:long abc = 123L;

因为java的整型是有符号类型的,0表示正数,1表示为负数,所以取值范围是从负多少到正多少,不能超过取值范围

整数的值的表示支持二进制,八进制,十进制,十六进制

byte:-128 ~ 127 长度8位 short: -32768 ~ 32767 长度16位 int: -2147483648 ~ 2147483647 长度32位 long: -9223372036854775808 ~ 9223372036854775807 长度64位

浮点型

浮点型类型:float(长度32位),double(长度64位)

浮点型默认为double,在数值后加F,代表为float类型,例如:float abc = 3.14F;

浮点型支持科学计数法(E或者e),e2就是代表为10的2次方,例如:3.14e2 = 3.14x100

float:3.4E-038 ~ 3.4E+038 double:1.7E-308 ~ 1.7E+308

浮点类型的数就是小数

小数值默认位double类型

如果想将一个小数类型设置为float类型,需要在小数后加f,例如:float abc = 3.14 f

float(单精度)精度是7位有效数字,第7位数字后面的会四舍五入

float a = 0.987654321f; // 实质上为0.9876543 ,2和1被四舍五入了,使用float类型,要在后面加上f

double(双精度)精度是16位有效数字

在计算机中,使用符号位(sign)+指数(exponent)+小数位(fraction),来表示浮点数(浮点表示法)

符号位表示正负,指数表示取值范围,小数位表示计算精度

例如: float类型为32位,符号位占1位,指数位占8位,小数位占23位,小数位不足位数的补0

double类型为64位,符号位占1位,指数占11为,小数位占52位,小数位不足位数的补0

布尔类型

java布尔类型和很多程序语言一样,用来表示真与假,布尔类型只有两个值,true和false,长度为1位

可以赋值变量为布尔类型,也可以通过关系运算来返回

例如:

boolean a = true;

boolean b = 1>2;

字符类型

字符类型char表示一个字符,char类型不但可以表示标准的ASCII,还可以表示一个Unicode字符

char类型使用单引号’‘来表示,而且只能存储一个字符,长度为16位

字符串

字符串类型String是一个引用类型,例如:

String a = “abc”;

引用类型的变量是类似于c语言的指针,内部保存了一个地址,指向某一个对象在内存的位置

\代表为转义符,例如:\n

类型转换

精度小的类型可以自动转换为精度大的类型 精度大的类型,需要强制转换,才能转换到精度小的类型,而且还可能溢出

例如:

自动转换

int a= 100;

long b;

a =b;

强制转换

int a = 999;

byte a = (byte)b;

因为byte类型取值范围为:-128 ~ 127,999超过了byte类型的取值范围

如果一个变量在类下声明,那么这个变量整个类都可以访问,其作用域就在其声明的那个类中,覆盖整个类

当一个变量在一个方法内部被定义,那么这个变量只能作用于该方法内部,这也叫为局部变量,方法一执行结束,该变量就被销毁

常量

使用final修饰符定义常量,例如

final int a = 123;

常量在定义时初始化后就不能重新赋值了,常量的命名习惯为全部大写

var 关键字

var关键字会自动推断变量的类型,使用var定义变量只是少写了变量类型,例如

var a = 123;

运算

整数的运算,是精确的,因为只取结果的整数部分

溢出:指一个数超过数据类型的取值范围了,只要这个数超出了取值范围,那么就会产生溢出,溢出不会报错,会返回一个数,这个数会通过二进制运算来处理

+=,-=,*=,/=

例如: a+=2 // 相当于 a = a + 2

++和–运算

a++ // 相当于 a = a + 1 a– // 相当于 a = a - 1

a++和++a

++a ,表示先加1,再引用a,a++,表示引用a,再加1

>大于,>=大于或等于,<小于,<=小于或等于,==是否相等,!=是否不相等

&:与,当俩边都为真时,为真,两边的表达式都处理 &&:与,当俩边都为真时,为真,只要第一个表达式的值为假,第二个就不进行处理 |:或,当两边都为假时,为假,任意一个表达式的值为真,则为真,两边的表达式都处理 ||:或,当两边都为假时,为假,任意一个表达式的值为真,则为真,只要第一个表达式的值为真,第二个就不进行处理 !:取反,当表达式的值为真时,返回假,表达式的值为假时,返回真 ^:异或,表达式的值不同时,返回真,相同时返回假

移位运算

因为在计算机中整数是以二进制表示的,所以可以通过移位运算

Integer.toBinaryString() 方法可以将十进制转换为二进制,例如:

int a =10; String b = (Integer.toBinaryString(a));

b的值为1010

例如:

int abc = 100;

int a = abc « 3; // 向左移动3位 a = 800

int b = abc » 3; // 向右移动3位,b = 12

int c = -1 »> 2; // 无符号向右移,c = 1073741823

位或|:当对应的二进位中,有一个为1时,结果为1,例如

1|2 : 1的二进制为1,2的二进制为10,那么得到的二进制结果为11,转换为十进制为3

位与&:当对应的二进位中,俩边都为1时,结果为1,例如

1&2 :二进制结果为10,十进制结果为2

异或^:当对应的二进位中,两边的值都不为1时,结果为1,例如:

1^2:二进制结果为01,十进制结果为1

取非~:将二进制位倒反,将0改为1,将1改为0,例如:

int a = 10 // 10的二进制为1010

~a // 值为0101,十进制结果为5

= :赋值 += : 自加,例如i+=1,那么等于i=i+1 -=:自减,例如i-=1,那么等于i=i-1 还有%=,&=,/=,|=,^=,«=,»=,»>=都是类似的

三元操作符

基础语法为:

a=x>c?值1:值2

用if语句来看就等于:

if(x>c){ a=值1 }else{ a=值2 }

if判断

根据条件来执行或者不执行某段语句,基本语法例如:

if(条件){ // 当条件满足时执行的语句 }else{ // 当条件不满足时执行的语句 }

例如: if(a>=100){ System.out.println(“a大于或者等于100”); }else{ System.out.println(“a不大于或者等于100”); }

switch判断

根据表达式的结果来执行相对应的语句,例如:

switch(a){ case 1: System.out.println(“a等于1”); break; case 2: System.out.println(“a等于2”); break; default: System.out.println(“不知道a等于多少”); }

switch也可以匹配字符串

while循环

循环就是根据条件进行循环处理,当条件满足时循环处理,当条件不满足时退出循环

例如:

while (a>=100){ System.out.println(a); a++; } while循环是先判断后循环处理,当初始条件不满足时,那么一次循环都不会发生

do…while就是先执行再判断条件,例如:

do{ System.out.println(a); a++; }while (a>=100);

先执行do里面的语句,再判断条件是否满足,所以do…while最低也会执行一次,哪怕初始条件也是不满足的

for循环

for和while不一样,它是使用计数器(自增或者自减)来实现循环,例如:

for (int a=1;a<=100;a++){ system.out.println(a); }

for可以用于数组遍历

break语句用于退出当前循环

continue语句用于提前结束本次循环,直接执行下次循环

例如:

for (int a=1;a<=100;a++){ system.out.println(a); if(a==2){ break; } if(a==3){ continue; }

数组

数组的定义及遍历

int[] arr = {5,1,3,7,8,2,6,0,10,4,9};

for (int i=0;i<arr.length;i++){ system.out.println(arr[i]); }

循环遍历的另一种方式

for(int a:b){ System.out.println(a); }

数组的每一个元素都可以通过索引来访问,数组的索引是从0开始,例如数组的第一个元素,就是arr[0],通过for循环,当i不小于时停止循环,i为索引值,arr.length为该数组的长度,从而达到输出数组的元素

int[] arr = {5,1,3,7,8,2,6,0,10,4,9};

for (int i;arr){ system.out.println(i); }

i:arr方法可以让变量i拿到arr数组的元素,而不是通过索引获取arr数组的值

多维数组的定义及遍历

Int[][] arr={{1,4,6},{,3,5,7},{9,2,2}};

for (int i=0;i<arr.length;i++){ for(int r=0;r<arr[i].length;r++){ system.out.println(arr[i][r]);

} }

通过for嵌套,达到遍历二维数组及多维数组

数组的排序

冒泡排序

int[] arr = {5,1,3,7,8,2,6,0,10,4,9};

for (int i=0;i<arr.length-1;i++){ for(int r=0;r<arr.length-i-1;r++){ if(arr[r]>arr[r+1]{ int a = arr[r]; arr[r]=arr[r+1]; arr[r+1] =a; ) } } system.out.println(Arrays.toString(arr));

通过循环,将相邻的数的位置互换,最大的数被换到末尾,对数组的排序是会修改数组本身,最好新建个数组,将数组的元素放入新的数组里,操作新的数组

arraycopy(被复制的数组,从被复制数组中复制数组的开始位置,需要复制的目标数组,复制到目标的数组的开始位置,复制的长度)

二维数组

int a[][] = new int[][]{ {1,2,3}, {9,8,7} };

int a[][] = new int[9][8]; # 有9个一维数组,每个一维数组的长度为8,

a[3][6]=88; # 可以直接访问已经定义好的数组,并且赋值

众所周知,java是一门面对对象的语言

面向对象的实现是继承性和多态性

面向对象的概念是方法,类,实例

面对对象基础

类是实例的构造,类是实例模板,定义了创建实例的方法,实例是根据类创建

定义类

class Hallo{ public int a; public String b; public double c; }

一个类可以包含字段,字段用于描述类的特征,这里定义了三个字段,分别是int类型的,命名为a,string类型的,命名为b,double类型的,命名为c,通过将这一组数据放在一个对象上,达到数据封装

创建实例

Hallo abc = new Hallo();

建立一个Hallo类的实例,通过变量abc指向该实例,Hallo abc是定义Hallo类型的变量abc,new Hallo()才是创建Hallo实例

实例可以通过变量.字段方法来访问到实例变量,例如:

Go maina = new Go(); maina.a = 18; maina.b =“hallo”; maina.c = 1.2; System.out.println(maina.b);

}

}

class Go { public int a; public String b; public double c; }

注意:在不同的实例中定义的变量,即便变量名相同,但是在内存中,是不同的,互不干扰,可以理解为局部变量的意思

并不建议在实例中直接操作字段,这样会破坏封装性

方法

使用private修饰的字段,外部程序是不能访问这些字段的,为了处理这个问题,需要用到方法来间接处理这些字段

Go maina = new Go(); maina.setA(18); maina.setB(“hallo”); System.out.println(maina.getA()+maina.getB); } } class Go { private int a; private String b;

public int getA(){
    return this.a;
}

public void setA(int a) {
    this.a = a;
}

public String getB(){
    return this.b;
}

public void setB(String b) {
    this.b = b;
}

}

外部程序通过调用方法getA()和getB()来间接修改字段

一个类通过定义方法,应该给外部程序提供可以操作的api,也要保证内部的逻辑性

调用方法:实例.方法(参数);

private方法

该方法不允许外部调用,主要是在内部方法调用

public class hallo { public static void main(String[] args) { go oo = new go(); oo.setAge(2002); System.out.println(oo.getAge());

}

} class go{ private String name; private int age;

public void setAge(int age){
    this.age = age;
}
public int getAge(){
    return abc(2020);
}
private int abc(int xyz){
    return xyz - this.age;
}

}

abc() 就是一个private方法

this变量

在方法内部,有一个变量this,这个变量始终指向当前的实例,例如this.age

一般来说,命名没有冲突,可以省略this,但是如果字段同名或者有局部变量,那么必须要加上this

方法参数

方法可以提供0个或者任意个参数,方法参数用于提供变量给方法 例如 class hallo{ public void abc(int age, String name){}

参数必须要符合个数要求和数据类型要求

package包

package hallo; # 声明该类处在那个包中

import hallo.yes; # 导入类中需要的类(用来导入其他包的类)

访问修饰符

修饰符有四种:

private # 私有的

package/friendly/default # 不可写的

protected # 受保护的

public # 公共的

例如:public String yes;

类与类之间的关系

继承:指一个类继承另一个类的功能,来增加本身的功能

实现:指一个类实现接口功能,是类和接口之间最常见的关系

依赖:指一个类使用了另一个类,而依赖于另一个类,另一个类发生改变有可能导致影响当前类

关联:和依赖关系类似,不过是更强的依赖关系,关联关系可以单向关联,也可以双向关联

聚合:和关联关系类似,不过整体和部分可以分离,有独自的生命周期

组合:和关联关系类似,不过整体和部分不可以分离,整体的生命周期结束后那么部分的生命周期也结束了

private:本身可以访问,但是不能继承类,不能访问同包下的类和其他包下的类

package/friendly/default :本身可以访问,同包下的类可以继承,不同包下的类不能继承,可以访问同包下的类,不能访问不同包下的类

protected:本身可以访问,同包下的类可以继承,不同包下的类可以继承,可以访问同包下的类,不能访问不同包下的类

public:本身可以访问,同包下的类可以继承,不同包下的类可以继承,可以访问同包下的类,可以访问不同包下的类

访问修饰符一般用来封装,将每一个类的作用明确化

实例属性和类属性

当一个属性声明为类属性,那么所有的对象都可以使用这个值,例如:

public class Untitled {
    public String name; // 对象属性
    static String yes; // 类属性

    public static void main(String[] args) {
        Untitled main =  new Untitled();
        main.name = "yes";
        Untitled.yes = "gg";
        System.out.println(main.name);
        System.out.println(main.yes);
        Untitled max =  new Untitled();
        max.name = "no";
        System.out.println(max.name);    
        System.out.println(max.yes);
    }
}

输出yes,gg,no,gg

可以通过main.yes和UntUntitled.yes来访问类属性

只有当一个类的所有对象的某个值都相同时,可以使用类属性

当一个类的对象的某个值不同时,使用实例属性,让这个值可以根据对象的不同来自定义

类方法和实例方法

实例方法必须要有对象才能调用,但是类方法可以直接通过类来调用,不需要对象的存在

例如:

public class Untitled {
    public String name; 
    protected String yes;
    public void hallo(){
        yes = "hallo word";
        System.out.println(yes);
    }
    public static void name() {
        System.out.println("hallo java");
    }
    
     
    public static void main(String[] args) {
        Untitled main =  new Untitled();
        main.hallo();
        Untitled.name();
    }
}

可以通过main.name()或者UntUntitled.name()来调用类方法

如果在一个方法中调用了对象属性,那么使用实例方法,如果在一个方法中没有调用任何对象属性,那么使用类方法


java输出中文乱码,可能是javac读取java文件使用的字符集错误

javac -encoding utf-8 *.java


java已放弃学习,主打golang和Python了(java又臭又长,快来加入golang教吧)