JAVA程序设计语言(图书+自学笔记)(持续更新)

自学java

  • Java

图书资源下载地址:
链接: https://pan.baidu.com/s/1vmywQiCVmFO8cqMD0cYWOQ
提取码:ewhq

Java

程序由类构成,根据类创建出任意数量的对象,对象即实例,类包含字段和方法

Java编写程序的第一个程序,任意编辑器新建文件Helloworld.java输入:

class Helloworld{
   public static void main(String[] args){
   System.out.println("Hello,world");
}
}

打开cmd,cd切换至安装目录,输入
javac Helloworld.java
java Helloworld
查看输出 Hello,world

这段代码在Helloworld类中定义了名为main的方法,main方法中可以创建对象,计算表达式,或是调用其他方法。

void表示没有返回据类型,
public表示java虚拟机任何对象都能够调用它。

斐波纳契数列表示后续项是前两项的和,我们来尝试编写下,新建Fibonacci.java:

class Fibonacci{
   public static void main(String[] args){
         int lo =1;
         int hi =1;
         System.out.println(lo);
         while(hi<50){
            System.out.println(hi);
            hi = hi+lo;
            lo = hi-lo;
}
}
}

在Fibonacci类的main方法中定义了两个32位的整型变量。

基本的数据类型有:
boolean 真(ture)或假(false)
char 16位字符型
byte 8位整型
short 16位整型
int 32为整型
long 64位整型 (需要在数据后面加l)
float 32位浮点型
double 64位浮点型

整形变量的几种表示形式:
十进制整数,如:99, -500, 0
八进制整数,要求以 0 开头,如:015
十六进制数,要求 0x 或 0X 开头,如:0x15
二进制数,要求0b或0B开头,如:0b01110011

引用数据类型:
类(class)
接口()

println在上述例子中分别是string和int类型的引元,其是众多重载的方法之一,能接受不同类型的引元,运行时系统会根据传入的引元数量和类型决定具体调用那一方法。

课后训练:
请使用java语句输出一组0~50的平方数,方法:
i*i
Math.pow(n,2)

详细代码:

class SquareData{
    public static void main(String[] args){
    int i=1;
    double s=0;
        System.out.println("输出从0~50的平方数");
    System.out.println(s);
    while(s<49){
        s=Math.pow(i,2);
        System.out.println(s);
        i++;
    }
    }
}

代码间的注释:
(1)多行注释: /* ·········/
(2)单行注释:// ············
(3)文本注释:/
·········/

具名常量:指通过名字来引用的常量值,一般全大写。
为了保证静态字段不变,则将字段申明为final,
为了保证具名常量字段和类的实例不像关联,则声明为:static,如:
final static int MAX = 50;
该语句必须用到main的方法外部;

控制流:描述决定程序中待执行语句及执行顺序的机制,常用控制流语句:
while
for
if - else
switch
do-while

为Fibonacci数中的偶数加上*号:

class ImprovedFibonacci{
    static final int Max_INDEX = 9;  //最大输出数目
    /*主函数*/
    public static void main(String[] args){
        int lo = 1;
        int hi = 1;
        String mark;
        System.out.println("1:"+lo);
        for(int i=2;i<=Max_INDEX;i++){
            if(hi%2==0){
                mark = "*";
                }
            else{
                mark = " ";
                }
            System.out.println(i+":"+hi+mark);
            hi = hi+lo;
            lo = hi-lo;
            }
        }
    }

运行后:
JAVA程序设计语言(图书+自学笔记)(持续更新)_第1张图片
标示符的使用用法:
数字不能作为标示符的开头,
关键字不能作为标示符
可以使用汉字,但不推荐
#不能作为标示符的开头

java中的关键字(保留字):
JAVA程序设计语言(图书+自学笔记)(持续更新)_第2张图片


转义字符:
JAVA程序设计语言(图书+自学笔记)(持续更新)_第3张图片


变量的分类:
(1)局部变量 : 方法或语句块内部定义的变量。局部变量在使用前必须先声明、初始化(赋初值)再使用。
(2)成员变量:方法外部、类的内部定义的变量。会自动初始化成该类型的默认初始值。
(3)静态变量:使用static定义。 从属于类,生命周期伴随类始终。

常量:
指固定的值,常和关键字final搭配使用,常量一旦被初始化后不能再更改其值

命名规则:

所有变量、方法、类名:见名知意
类成员变量:首字母小写和驼峰原则: monthSalary
局部变量:首字母小写和驼峰原则
常量:大写字母和下划线:MAX_VALUE
类名:首字母大写和驼峰原则: Man, GoodMan
方法名:首字母小写和驼峰原则: run(), runRun()

运算符:
JAVA程序设计语言(图书+自学笔记)(持续更新)_第4张图片


方法
方法是一段用来完成特定功能的代码片段,相当于其他语言的的函数,其声明格式为:

[修饰符1  修饰符2  …]   返回值类型    方法名(形式参数列表){
    Java语句;… … …
 }

调用方式:

 对象名.方法名(实参列表)

说明一下
(1)形式参数:在方法声明时用于接收外界传入的数据。
(2) 实参:调用方法时实际传给方法的数据。
(3)返回值:方法在执行完毕后返还给调用它的环境的数据。
(4)返回值类型:事先约定的返回值的数据类型,如无返回值,必须显示指定为为void。


方法的重载
表示名称相同,实际是完全不同的方法,其重载的条件为:
(1)形参类型、形参个数、形参顺序不同
(2)只有返回值不同不构成方法的重载
(3)只有形参的名称不同,不构成方法的重载
案例:

public class Test21 {
    public static void main(String[] args) {
        System.out.println(add(3, 5));// 8
        System.out.println(add(3, 5, 10));// 18
        System.out.println(add(3.0, 5));// 8.0
        System.out.println(add(3, 5.0));// 8.0
        // 我们已经见过的方法的重载
        System.out.println();// 0个参数
        System.out.println(1);// 参数是1个int
        System.out.println(3.0);// 参数是1个double
    }
    /** 求和的方法 */
    public static int add(int n1, int n2) {
        int sum = n1 + n2;
        return sum;
    }
    // 方法名相同,参数个数不同,构成重载
    public static int add(int n1, int n2, int n3) {
        int sum = n1 + n2 + n3;
        return sum;
    }
    // 方法名相同,参数类型不同,构成重载
    public static double add(double n1, int n2) {
        double sum = n1 + n2;
        return sum;
    }
    // 方法名相同,参数顺序不同,构成重载
    public static double add(int n1, double n2) {
        double sum = n1 + n2;
        return sum;
    }
    //编译错误:只有返回值不同,不构成方法的重载
    public static double add(int n1, int n2) {
        double sum = n1 + n2;
        return sum;
    }
    //编译错误:只有参数名称不同,不构成方法的重载
    public static int add(int n2, int n1) {
        double sum = n1 + n2;         
        return sum;
    }  
}

递归结构:
自己调自己

组成:递归头(什么时候结束递归)+递归体(什么时候调用递归方法)

缺点:太耗资源,递归的方法可用循环来实现

获取系统时间的方法为:
System.currentTimeMillis();


面向对象的编程
宏观面像对象,微观面向过程。

面向对象具有三大特征:封装性、继承性和多态性,而面向过程没有继承性和多态性,并且面向过程的封装只是封装功能,而面向对象可以封装数据和功能

类(class)和对象(object)(实例 intstance):
1.对象是具体的事物;类是对对象的抽象;
2.类可以看成一类对象的模板,对象可以看成该类的一个具体实例。
3.类是用于描述同一类型的对象的一个抽象概念,类中定义了这一类对象所应具有的共同的属性、方法。

类的三个常见成员:
属性field、方法method、构造器constructor。这三种成员都可以定义零个或多个。


Java虚拟机的内存分为:栈stack、堆heap、方法区method area

1、栈的特点如下:
A: 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)
B:JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)
C:栈属于线程私有,不能实现线程间的共享!
D: 栈的存储特性是“先进后出,后进先出”
E:栈是由系统自动分配,速度快!栈是一个连续的内存空间!

2、堆的特点如下:
A:堆用于存储创建好的对象和数组(数组也是对象)
B:JVM只有一个堆,被所有线程共享
C:堆是一个不连续的内存空间,分配灵活,速度慢!

3、方法区(又叫静态区)特点如下:
A:JVM只有一个方法区,被所有线程共享!
B:法区实际也是堆,只是用于存储类、常量相关的信息!
C:用来存放程序中永远是不变或唯一的内容。(类信息【Class对象】、静态变量、字符串常量等)


构造器
构造的方法用于对象初始化

  1. 通过new关键字调用!
  2. 构造器虽然有返回值,但是不能定义返回值类型(返回值的类型肯定是本类),不能在构造器里使用return返回某个值。
  3. 如果我们没有定义构造器,则编译器会自动定义一个无参的构造函数。如果已定义则编译器不会自动添加!
  4. 构造器的方法名必须和类名一致!

构造器的重载
用于相同名称的不同方法的构造方法,如果方法构造中形参名与属性名相同时,需要使用this关键字区分属性与形参。其中this.id 表示属性id;id表示形参id。,例如:

public class User {
    int id; // id
    String name; // 账户名
    String pwd; // 密码
    
    public User() {
    }
    public User(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    public User(int id, String name, String pwd) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }
    public static void main(String[] args) {
        User u1 = new User();
        User u2 = new User(101, "高小七");
        User u3 = new User(100, "高淇", "123456");     
    }
}

垃圾回收机制(Garbage Collection)
java的内存管理指对对下岗的管理,包含对象空间的分配和释放
(1)对象空间的分配:使用new关键字创建对象即可。
(2)对象空间的释放:将对象赋值null即可。垃圾回收器将负责回收所有”不 可达”对象的内存空间

任何一种垃圾回收算法一般要做两件基本事情:
(1)发现无用的对象
(2)回收无用对象占用的内存空间

垃圾回收算法:
(1)引用计数法
(2)引用可达法


通用的分代垃圾回收机制
对象分为三种状态:年轻代、年老代、持久代。
JVM将堆内存划分为 Eden、Survivor 和 Tenured/Old 空间。
JAVA程序设计语言(图书+自学笔记)(持续更新)_第5张图片
其垃圾回收的过程如上图所示:
(1)新创建的对象,绝大多数都会存储在Eden中,
(2)当Eden满了(达到一定比例)不能创建新对象,则触发垃圾回收(GC),将无用对象清理掉,然后剩余对象复制到某个Survivor中,如S1,同时清空Eden区
(3)当Eden区再次满了,会将S1中的不能清空的对象存到另外一个Survivor中,如S2,同时将Eden区中的不能清空的对象,也复制到S1中,保证Eden和S1,均被清空。
(4)重复多次(默认15次)Survivor中没有被清理的对象,则会复制到老年代Old(Tenured)区中,
(5)当Old区满了,则会触发一个一次完整地垃圾回收(FullGC),之前新生代的垃圾回收称为(minorGC)

JVM调优主要是对FULLGC的调节


this关键字
this的本质就是“创建好的对象的地址”! 由于在构造方法调用前,对象已经创建。因此,在构造方法中也可以使用this代表“当前对象” 。
this最常的用法:
  1. 在程序中产生二义性之处,应使用this来指明当前对象;普通方法中,this总是指向调用该方法的对象。构造方法中,this总是指向正要初始化的对象。
  2. 使用this关键字调用重载的构造方法,避免相同的初始化代码。但只能在构造方法中用,并且必须位于构造方法的第一句。
  3. this不能用于static方法中。


static关键字:
static修饰成员变量和方法,从属于类,普通变量和方法从属与对象的。
用static声明的成员变量为静态成员变量,也称为类变量。
在static方法中不可直接访问非static的成员。


静态初始化


参数传值机制
java中方法中所有参数为值传递,传递的是值的副本。 副本改变不会影响原件


包机制
Java中管理类的重要手段,包对于类,相当于文件夹对于文件的作用,
(1)包名倒着写
(2)com.gao和com.gao.car,这两个包没有包含关系,是两个完全独立的包。只是逻辑上看起来后者是前者的一部分


JDK常用的包:
JAVA程序设计语言(图书+自学笔记)(持续更新)_第6张图片


继承使用要点
1: 父类也叫超类,基类,派生类
2:java只有单继承,没有多继承,对象有多继承
3: 子类继承父类,可以得到父类的全部属性和方法 (除了父类的构造方法),但不见得可以直接访问(比如,父类私有的属性和方法)。
4: 如果定义一个类时,没有调用extends,则它的父类是:java.lang.Object。
IDEA快速查看继承树:command +alt+U


instanceof运算符
二元运算符,左边为对象,右边为类,当对象是右边类或子类所创建的时候,返回true;否则返回false;比如:

public class TestInstanceof {
    public static void main(String[] args){
        Student student = new Student("gaoqi",143,"jisuanji");
        System.out.println(student instanceof Student);
        System.out.println(student instanceof Person);
    }
}

输出为true true


方法的重写override
子类重写父类的方法,可以用自身的行为替换父类的行为。方法的重写是实现多态的必要条件。

重写的三个条件
1. “==”: 方法名、形参列表相同。
2. “≤”:返回值类型和声明异常类型,子类小于等于父类。
3. “≥”: 访问权限,子类大于等于父类。


Object类
所有Java类的根基类,也就是所有的java对象都拥有Object类的属性和方法


equals方法:
Object 的 equals 方法默认就是比较两个对象的hashcode,是同一个对象的引用时返回 true 否则返回 false。但是,我们可以根据我们自己的要求重写equals方法。
提供定义“对象内容相等”


Super关键字:
super是直接父类对象的引用。可以通过super来访问父类中被子类覆盖的方法或属性。
使用super调用普通方法,语句没有位置限制,可以在子类中随便调用。
若是构造方法的第一行代码没有显式的调用super(…)或者this(…);那么Java默认都会调用super(),含义是调用父类的无参数构造方法。super()可以省略。
构造方法的第一句常用super()来调用父类对应的构造方法,流程一般是先向上追溯到Object 在依次向下执行类的初始化和构造方法,直到当前子类为止。


静态初始化顺序:调用 Object~父类~子类

属性/方法查找顺序:(比如:查找变量h)
1. 查找当前类中有没有属性h
2. 依次上溯每个父类,查看每个父类中是否有h,直到Object
3. 如果没找到,则出现编译错误。
4. 上面步骤,只要找到h变量,则这个过程终止。


封装
封装就是把对象的属性和操作结合为一个独立的整体,并尽可能隐藏对象的内部实现细节。
特点:
安全/复用/高内聚/低耦合

封装的实现
使用访问控制符,共有四种:private/default/protected/public,其访问权限见下图(*表示可以访问的权限范围):
JAVA程序设计语言(图书+自学笔记)(持续更新)_第7张图片
类的属性的处理:
1. 一般使用private访问权限。
2. 提供相应的get/set方法来访问相关属性,这些方法通常是public修饰的,以提供对属性的赋值与读取操作(注意:boolean变量的get方法是is开头!)。
3. 一些只用于本类的辅助性方法可以用private修饰,希望其他类调用的方法用public修饰。


多态
指同一种方法调用,由于对象不同可能有不同的行为
(1)多态是方法的多态,不是属性的多态
(2)多态的存在有三个必要条件,继承,方法重写,父类引用指向子类对象。
(3)父类引用指向子类对象后,该父类引用调用子类重写的方法,也就实现了多态


对象的转型
(1)类引用指向子类对象,我们称这个过程为向上转型,属于自动类型转换。
(2)向上转型后的父类引用变量只能调用它编译类型的方法,不能调用它运行时类型的方法。这时,我们就需要进行类型的强制转换,我们称之为向下转型!


final关键字
(1)修饰变量: 被他修饰的变量不可改变。一旦赋了初值,就不能被重新赋值。
(2)修饰方法:该方法不可被子类重写。但是可以被重载!
(3) 修饰类: 修饰的类不能被继承。比如:Math、String等。


数组
相同类型数据的有序集合,通过索引(下标)可以访问它的元素。数组的三个特点:长度确定/元素相同类型/数组为任何数据类型(基本数据类型和引用类型)

申明数组
申明的时候并没有实例化对象,只有实例化对象时,JVM才分配存储空间,数组对象存储在堆中

数组的初始化方法:
(1)静态初始化:
除了用new关键字来产生数组以外,还可以直接在定义数组的同时就为数组元素分配空间并赋值。如:

int[] a = { 1, 2, 3 };// 静态初始化基本类型数组;
Man[] mans = { new Man(1, 1), new Man(2, 2) };// 静态初始化引用类型数组;

(2)动态初始化
数组定义与为数组元素分配空间并赋值的操作分开进行。

int[] a1 = new int[2];//动态初始化数组,先分配空间;
a1[0]=1;//给数组元素赋值;
a1[1]=2;//给数组元素赋值;

(3) 默认初始化
数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。

int a2[] = new int[2]; // 默认值:0,0
boolean[] b = new boolean[2]; // 默认值:false,false
String[] s = new String[2]; // 默认值:null, null

数组的遍历
数组元素下标的合法区间:[0, length-1]。我们可以通过下标来遍历数组中的元素,遍历时可以读取元素的值或者修改元素的值。
for-each循环
增强for循环for-each是JDK1.5新增加的功能,专门用于读取数组或集合中所有的元素,即对数组进行遍历。

你可能感兴趣的:(JAVA)