快捷搜索: 长连接 前端 源码 pan

初学Java--第一篇

dos命令:

md mydir
rd mydir
rd /s mydir2                # 递归删除
rd /s /q mydir3             # quite 安静模式删除,不再询问是否确认全部删除
copy con 1.txt              # con console  ^Z保存退出
del *.txt
cls (clear screen)

JAVA专业名词

JVM

JRE 包含了JVM

JDK java开发工具包 :包含了JRE

JAVA_HOME 先新建JAVA_HOME全局变量,再将它加入PATH之中。

CLASSPATH 执行java test的时候,先在test.java当前目录找test.class文件找不到再去classpath中找

JAVA基础语法

关键字

特点:组成关键字单词的字母全部小写。

goto和const作为保留字,目前并不使用

关键字:

synchronized

native

strictfp

transient

volatile

assert

标识符

组成规则:英文大小写字母,数字字符,$和_。

常量

其中:单引号只能包含字符,不能包含字符串。

两种:一种就是字面值常量,还有一种是类里面用final形容的变量,在编译的时候会编译成常量。

常量:     一个单词:全部大写
                举例:PI
          多个单词:每个字母都大写,用_隔开
                举例:STUDENT_MAX_AGE

变量

//不能是Java中的关键字
    //int public = 100;
    int Public = 100; //正确

进制

不同进制的数据组成

二进制 以0b开头 System.out.println(0b100); //输出4

八进制 以0开头

十进制 整数默认是十进制的

十六进制 以0x开头(其中abcdef,大小写均可)

数据类型

包括:基本数据类型和引用数据类型。

基本数据类型包括:数值型、字符型、布尔型。

数值型包括:整数型和浮点型。

引用数据类型包括:类、接口、数组。


整型: byte 1字节 -2^7 ~ 2^7-1

short 2 -32 768 ~ 32 767

int 4 -2 147 483 648 ~ 2 147 483 647

long 8

float 4 -3.403*10^38 ~ 3.403*10^38

double 8

char 2

boolean 1


整数默认是int类型,浮点数默认是double类型。

        长整型后缀用L或者l标记。建议使用L。
        单精度浮点数用F或者f标记。建议使用F。
int x = 4;
    int y = (x++)+(++x)+(x*10);
    //4+6+60

boolean类型不能转换为其他的数据类型,其他类型也不能转化为boolen。

默认转换

byte,short,char—int—long—float—double

byte,short,char相互之间不转换,他们参与运算首先转换为int类型

强制转换

Integer a = (Integer)"122";  //Canot cast from String to Integer

Integer a = (Integer)a;   //Canot cast from String to Char

int a = (int)a;           //97

int a = (int)21474836472L;  // -8   (int是数据类型,Integer是一个类)
/* 编译和运行只会判断你的类型是否符合。溢出就会变成负数,所以一定要少用强制类型转化。 */

Student s = (Student) oPerson;
//字符串数据和其他数据做+,结果是字符串类型。这里的+不是加法运算,而是字符串连接符。
System.out.println("hello"+a+1); //helloa1

System.out.println(a+"hello"+1); //ahello1

System.out.println(a+1+"hello"); //98hello

‘a’ 是字符 ,”a” 是字符串 。作“+”运算时候,根据环境前者可能转化为ascii。后者不会。

s = s + 1; 和 s += 1;是不同的,s += 1;相当于 s = (s的数据类型)(s + 1) || 和 && 短路
位运算符的细节 << 空位补0,被移除的高位丢弃。 > 被移位的二进制最高位是0,右移后,空缺位补0;最高位是1,最高位补1。 > 被移位二进制最高位无论是0或者是1,空缺位都用0补。
^的特点:一个数据对另一个数据位异或两次,该数本身不变。
    int a = 10;
    int b = 20;

    System.out.println(a ^ b ^ b); //10
    System.out.println(a ^ b ^ a); //20

if关系表达式无论简单还是复杂,结果必须是boolean类型。

switch后的表达式的取值:byte,short,int,char。JDK5以后可以是枚举,JDK7以后可以是String。

int a = 2;
    int b = 3;
    switch(a){
        default:
            b++;
        case 3:
            b++;
        case 4:
            b++;
    }
    // b = 6;

循环结构的判断条件语句的值必须是boolean型。

for(;;){...}        //是一个死循环
if(b != 100);       //这里其实是有语句体的,只不过是空语句体。

方法

方法重载概述

在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。(包括静态)

方法之间是平级关系,不能嵌套定义。

数组

//定义
int[] a = {
         
  1, 2, 3};
int b[] = {
         
  2, 1, 3};

int[] arr = new int[3];
int[] arr = new int[]{
         
  1,2,3};       //是一维数组
int[] arr = {
         
  1,2,3};

//二维数组
int[][] arr = new int[3][2];

int[][] arr1 = new int[3][];
arr1[0] = new int[2];
arr1[1] = new int[3];
arr1[2] = new int[1];

int[][] arr =  {
         
  {
         
  1,2,3},{
         
  4,6},{
         
  6}};
wc:for(int x=0; x<3; x++) {
        nc:for(int y=0; y<4; y++) {
            if(y == 2) {
                break nc;
                //break wc;
            }
            System.out.print("*");
        }
        System.out.println();
    }
    /*
    输出如下:
    **
    **
    **
    */

栈 存储局部变量 (存放局部变量;用完即删)没有默认值,所以必须初始化。

堆 存储new出来的东西 (存放对象;用完会等到垃圾回收程序空闲的时候删除)。有默认值:

byte,short,int,long     0
float,double            0.0
char                    u0000
boolean                 false
引用类型                 null

方法区 (面向对象部分讲)

本地方法区 (和系统相关)

寄存器 (给CPU使用)

数组是内置的类,所以int[] arr = {1,2,3}; int[] arr2 = arr;后续改变arr2的值,会导致arr的值也做相应变化。 纠正上面的 错误,= 设计的不是类不类的,是关于数据类型的。当类型是引用类型的时候,两个变量的值是地址值。所以指向引用类型的同一个地方。所以更改一个,另一个随之变化。
byte,short在定义的时候,他们接收的其实是一个int类型的值。
Java语言中的字符char可以存储一个中文汉字吗?为什么呢?
可以。因为java语言中的字符占用两个字节。

Java语言采用的是Unicode编码。

类和对象

### 构造方法

没有返回值类型,连void都没有,可以有return;

如果你不提供构造方法,系统会给出默认构造方法。
如果你提供了构造方法,系统不再提供。此时想调用无参构造,必须自己定义。所以推荐任何时候自己给出无参构造。
构造方法也是可以重载的。  

  Student s = new Student();做了哪些事情?(理解)
    (1)把Student.class文件加载到内存
    (2)在栈内存为s开辟空间
    (3)在堆内存为学生对象申请空间
    (4)给学生的成员变量进行默认初始化。null,0
    (5)给学生的成员变量进行显示初始化。林青霞,27
    (6)通过构造方法给成员变量进行初始化。刘意,30
    (7)对象构造完毕,把地址赋值给s变量

static

被类的所有对象共享
    这也是我们判断是否使用静态关键字的条件。
静态方法只能访问静态的成员变量和静态的成员方法
    静态在非静态前加载。
静态的内容存在于方法区的静态区

代码块

局部代码块
    在方法中出现;限定变量生命周期,及早释放,提高内存利用率
构造代码块
    在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
静态代码块
    在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且值执行一次
同步代码块

执行顺序
    静态代码块、构造代码块、构造方法。(静态代码块是在初始化类的时候才运行,不是类加载的时候运行的。)
class Fu {
    static {
        System.out.println("静态代码块Fu");
    }

    {
        System.out.println("构造代码块Fu");
    }

    public Fu() {
        System.out.println("构造方法Fu");
    }
}

class Zi extends Fu {
    static {
        System.out.println("静态代码块Zi");
    }

    {
        System.out.println("构造代码块Zi");
    }

    public Zi() {
        System.out.println("构造方法Zi");
    }
}

class a {
    public static void main(String[] args) {
        Zi z = new Zi();
    }
}

/*
结果是:
        静态代码块Fu
        静态代码块Zi
        构造代码块Fu
        构造方法Fu
        构造代码块Zi
        构造方法Zi
*/

--------------------------------------------------------------------------------------------

/*
    输出:

    林青霞都60了,我很伤心
    我是main方法
    Student 静态代码块
    Student 构造代码块
    Student 构造方法
    Student 构造代码块
    Student 构造方法
*/
class Student {
    static {
        System.out.println("Student 静态代码块");  //一次性
    }

    {
        System.out.println("Student 构造代码块");
    }

    public Student() {
        System.out.println("Student 构造方法");
    }
}

class StudentDemo {
    static {
        System.out.println("林青霞都60了,我很伤心");
    }

    public static void main(String[] args) {
        System.out.println("我是main方法");

        Student s1 = new Student();
        Student s2 = new Student();
    }
}
main方法所在的类的构造方法不会运行。

方法重载能改变返回值类型吗?
    方法重载能改变返回值类型,因为它和返回值类型无关。

this:代表当前类的对象引用
super:代表父类存储空间的标识。

匿名对象

匿名对象的应用场景:
    A:调用方法,仅仅只调用一次的时候。
        注意:调用多次的时候,不适合。
        那么,这种匿名调用有什么好处吗?
        有,匿名对象调用完毕就是垃圾。可以被垃圾回收器回收。
    B:匿名对象可以作为实际参数传递

new Student().show();
teacher.method(new Student());

继承

子类中所有的构造方法默认都会访问父类中空参数的构造方法。(无参!!!不会访问有参)

在任何的void类型的方法的最后你都可以写上:return;

父类静态方法,子类也必须通过静态方法进行重写。在多态中,静态方法就不能算是重写了。

final

final修饰局部变量
    在方法内部,该变量不可以被改变
    在方法声明上
        基本类型,是值不能被改变
        引用类型,是地址值不能被改变
final修饰变量的初始化时机
    在对象构造完毕前即可

abstract

抽象类的成员特点:
    成员变量:既可以是变量,也可以是常量。
    构造方法:有。
                用于子类访问父类数据的初始化。
    成员方法:既可以是抽象的,也可以是非抽象的。

抽象类的成员方法特性:
    A:抽象方法 强制要求子类做的事情。
    B:非抽象方法 子类继承的事情,提高代码复用性。

abstract不能和哪些关键字共存?
    private 冲突
    final   冲突  
    static  无意义 (解释:抽象类中的静态方法可以通过类名直接调用。但是abstract方法是没有方法体的,调用                了无意义。)

interface

//Java中就提供了接口来定义这些额外功能,并不给出具体实现,将来哪些猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可。
接口不能实例化
    那么,接口如何实例化呢?
    按照多态的方式,由具体的子类实例化。其实这也是多态的一种,接口多态。(abstract 同理)
接口的子类
    要么是抽象类
    要么重写接口中的所有抽象方法
成员变量
    只能是常量
    默认修饰符 public static final
构造方法
    没有,因为接口主要是扩展功能的,而没有具体存在
成员方法
    只能是抽象方法
    默认修饰符 public abstract

抽象类和接口的区别

成员区别
    抽象类     变量,常量;有抽象方法;抽象方法,非抽象方法
    接口       常量;抽象方法
关系区别
    类与类     继承,单继承
    类与接口    实现,单实现,多实现
    接口与接口   继承,单继承,多继承
设计理念区别
    抽象类     被继承体现的是:”is a”的关系。共性功能
    接口      被实现体现的是:”like a”的关系。扩展功能
public protected 默认 private 同一类中 √ √ √ 同一包子类,其他类 √ √ √ 不同包子类 √ √ 不同包其他类 √

public 哪儿都可以访问

protected 只要是本类、子类就能访问

private 只有本类可以访问

默认 只要是在同一个包下就能访问

类:
    默认,public,final,abstract
    我们自己定义:public居多
成员变量:
    四种权限修饰符均可,final,static
    我们自己定义:private居多
构造方法:
    四种权限修饰符均可,其他不可
    我们自己定义:public 居多
成员方法:
    四种权限修饰符均可,fianl,static,abstract
    我们自己定义:public居多

内部类

内部类的访问特点:
    内部类可以直接访问外部类的成员,包括私有。
    外部类要访问内部类的成员,必须创建对象。

两种格式:成员位置(成员内部类),局部位置(局部内部类).

成员内部类
    外界如何创建对象
    外部类名.内部类名 对象名 = 外部类对象.内部类对象;
    成员内部的常见修饰符
        private 为了保证数据的安全性
        static 为了让数据访问更方便
        被静态修饰的成员内部类只能访问外部类的静态成员
        内部类被静态修饰后的方法
            静态方法    
            非静态方法
局部内部类
    可以直接访问外部类的成员
    可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
    局部内部类访问局部变量的注意事项:
        必须被final修饰。
        为什么呢?
            因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用                  那个变量。为了让数据还能继续被使用,就用fianl修饰,这样,在堆内存里面存储的其实是一个                   常量值。通过反编译工具可以看一下
匿名内部类
    就是内部类的简化写法。
    前提:存在一个类或者接口
    这里的类可以是具体类也可以是抽象类。
    格式:
        new 类名或者接口名() {重写方法;}
    本质:
        是一个继承了类或者实现了接口的子类匿名对象

匿名内部类面试题
    interface Inter { void show(); }
    class Outer { //补齐代码 }
    class OuterDemo {
        public static void main(String[] args) {
              Outer.method().show();
          }
    }
要求在控制台输出”HelloWorld”
成员变量和局部变量的区别?
    A:在类中的位置不同
        成员变量:在类中方法外
        局部变量:在方法定义中或者方法声明上
    B:在内存中的位置不同
        成员变量:在堆内存
        局部变量:在栈内存
    C:生命周期不同
        成员变量:随着对象的创建而存在,随着对象的消失而消失
        局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
    D:初始化值不同
        成员变量:有默认初始化值
        局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。


    注意事项:
        局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。
变量什么时候定义为成员变量:
    如果这个变量是用来描述这个类的信息的,那么,该变量就应该定义为成员变量。

变量到底定义在哪里好呢?
    变量的范围是越小越好。因为能及时的被回收。
static的特点:(它可以修饰成员变量,还可以修饰成员方法)
    A:随着类的加载而加载
        回想main方法。
    B:优先于对象存在
    C:被类的所有对象共享
        举例:咱们班级的学生应该共用同一个班级编号。
        其实这个特点也是在告诉我们什么时候使用静态?
            如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。
        举例:
            饮水机(用静态修饰)
            水杯(不能用静态修饰)
    D:可以通过类名调用
        其实它本身也可以通过对象名调用。
        推荐使用类名调用。

        静态修饰的内容一般我们称其为:与类相关的,类成员
static关键字注意事项
    A:在静态方法中是没有this关键字的
        如何理解呢?
            静态是随着类的加载而加载,this是随着对象的创建而存在。
            静态比对象先存在。
    B:静态方法只能访问静态的成员变量和静态的成员方法
            静态方法:
                成员变量:只能访问静态变量
                成员方法:只能访问静态成员方法
            非静态方法:
                成员变量:可以是静态的,也可以是非静态的
                成员方法:可是是静态的成员方法,也可以是非静态的成员方法。
        简单记:
            静态只能访问静态。

静态方法中可以直接用方法名调用静态方法;但是非静态方法,必须先生成对象,再去调用。

所以静态方法中访问其他静态方法可以用三种方式,直接调用、类名调用、对象名调用。

继承中构造方法的关系
    A:子类中所有的构造方法默认都会访问父类中空参数的构造方法
    B:为什么呢?
        因为子类会继承父类中的数据,可能还会使用父类的数据。
        所以,子类初始化之前,一定要先完成父类数据的初始化。

        注意:子类每一个构造方法的第一条语句默认都是:super();

如果父类没有无参构造方法,那么子类的构造方法会出现什么现象呢?

/* 如果父类没有无参构造方法,那么子类的构造方法会出现什么现象呢?
    报错。
如何解决呢?  
    A:在父类中加一个无参构造方法
    B:通过使用super关键字去显示的调用父类的带参构造方法
    C:子类通过this去调用本类的其他构造方法
        子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化。

注意事项:
    this(...)或者super(...)必须出现在第一条语句上。
    如果不是放在第一条语句上,就可能对父类的数据进行了多次初始化,所以必须放在第一条语句上。
*/
class Father {
    /*
    public Father() {
        System.out.println("Father的无参构造方法");
    }
    */

    public Father(String name) {
        System.out.println("Father的带参构造方法");
    }
}

class Son extends Father {
    public Son() {
        super("随便给");
        System.out.println("Son的无参构造方法");
        //super("随便给");
    }

    public Son(String name) {
        //super("随便给");
        this();
        System.out.println("Son的带参构造方法");
    }
}

class ExtendsDemo7 {
    public static void main(String[] args) {
        Son s = new Son();
        System.out.println("----------------");
        Son ss = new Son("林青霞");
    }
}

多态

多态的弊端:
    不能使用子类的特有功能。

我就想使用子类的特有功能?行不行?
行。

怎么用呢?
    A:创建子类对象调用方法即可。(可以,但是很多时候不合理。而且,太占内存了)
    B:把父类的引用强制转换为子类的引用。(向下转型)

对象间的转型问题:
    向上转型:
        Fu f = new Zi();
    向下转型:
        Zi z = (Zi)f; //要求该f必须是能够转换为Zi的。
/**
我对多态的理解:
Fu f = new Zi();
不考虑内存存储关系。理解是这个样子:f有父类的所有的属性和静态功能。(其中非静态功能是Zi()的。)
考虑内存中才存储。f的存储会是f类的样子,并同名的非静态方法被覆盖。



详解:
Animal d = new Dog();
1. 栈内存有个标志为d,值为0x0001;
2. 堆内存的地址0x0001:放了成员变量age=12, height=22, animal.eat(0x00a.eat), animal.fly(0x00a.fly)
        因为是new dog,所以 animal.eat(0x00a.eat) 被覆盖成了 dog.eat(0x00d.eat)
        【其中0x00a.eat代表的是animal.eat在方法区中的地址。】

Dog dd = (Dog)d;
1. 栈内存中,标识符dd,值为0x0001;
2. 堆内存的地址0x0001:已有的东西不会删除,新来的Dog里的属性和方法会直接覆盖已有的。所以最后有
        age=3, height=22, color="white", dog.eat(0x00d.eat), animal.fly(0x00a.fly)
        dog.door((0x00d.door)


**/
class Animal {
    int age = 12;
    int height = 22;
    public void eat(){
        System.out.println("eat");
    }

    public void fly(){
        System.out.println("sleep");
    }
}

class Dog extends Animal {
    int age = 3;
    int color = "white";
    public void eat(){
        System.out.println("狗吃肉");
    }

    public void door(){
        System.out.println("狗door");
    }
}
/*
继承的时候:
        子类中有和父类中一样的方法,叫重写。
        子类中没有父亲中出现过的方法,方法就被继承过来了。
*/
class A {
    public void show() {
        show2();        // 这边改成 this.show2(); 答案也是 爱你。    体现了“重写”的特征
    }
    public void show2() {
        System.out.println("我");
    }
}
class B extends A {
    /*
    public void show() {
        show2();
    }
    */

    public void show2() {
        System.out.println("爱");
    }
}
class C extends B {
    public void show() {
        super.show();
    }
    public void show2() {
        System.out.println("你");
    }
}
public class leon {
          
   
    public static void main(String[] args) {
        A a = new B();
        a.show();

        B b = new C();
        b.show();
    }
}

接口

接口的特点:
    A:接口用关键字interface表示 
    B:类实现接口用implements表示
    C:接口不能实例化
        那么,接口如何实例化呢?
        按照多态的方式来实例化。
    D:接口的子类
        a:可以是抽象类。但是意义不大。
        b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)

由此可见:
    A:具体类多态(几乎没有)
    B:抽象类多态(常用)
    C:接口多态(最常用)
接口成员特点
    成员变量;只能是常量,并且是静态的。
            默认修饰符:public static final   因为static,所以可以通过接口名直接访问。
            建议:自己手动给出。
    构造方法:接口没有构造方法。
    成员方法:只能是抽象方法。
            默认修饰符:public abstract
            建议:自己手动给出。

形式参数和返回值的问题(理解)

(1)形式参数:
    类名:需要该类的对象
    抽象类名:需要该类的子类对象
    接口名:需要该接口的实现类对象
(2)返回值类型:
    类名:返回的是该类的对象
    抽象类名:返回的是该类的子类对象
    接口名:返回的是该接口的实现类的对象
(3)链式编程
    对象.方法1().方法2().......方法n();

    这种用法:其实在方法1()调用完毕后,应该一个对象;
              方法2()调用完毕后,应该返回一个对象。
              方法n()调用完毕后,可能是对象,也可以不是对象。

常见的修饰符(理解)

(1)分类:
    权限修饰符:private,默认,protected,public
    状态修饰符:static,final
    抽象修饰符:abstract
(2)常见的类及其组成的修饰
    类:
        默认,public,final,abstract

        常用的:public

    成员变量:
        private,默认,protected,public,static,final

        常用的:private

    构造方法:
        private,默认,protected,public

        常用的:public

    成员方法:
        private,默认,protected,public,static,final,abstract

        常用的:public
(3)另外比较常见的:
    public static final int X = 10;
    public static void show() {}
    public final void show() {}
    public abstract void show();

内部类

内部类的分类
    A:成员内部类
        a:private 为了数据的安全性
        b:static 为了访问的方便性

        成员内部类不是静态的:
            外部类名.内部类名 对象名 = new 外部类名.new 内部类名();
        成员内部类是静态的:
            外部类名.内部类名 对象名 = new 外部类名.内部类名();
                    30,20,10

        class Outer {
            public int num = 10;

            class Inner {
                public int num = 20;

                public viod show() {
                    int num  = 30;

                    System.out.println(num);
                    System.out.println(this.num);
                    System.out.println(Outer.this.num);
                }
            }
        }

    B:局部内部类
        a:局部内部类访问局部变量必须加final修饰。(反编译时候可以看见变成了常量)
        b:为什么呢?
            因为局部变量使用完毕就消失,而堆内存的数据并不会立即消失。


    C:匿名内部类
        a:是局部内部类的简化形式
        b:前提
            存在一个类或者接口
        c:格式:
            new 类名或者接口名() {
                重写方法;
            }
                    interface Person {
                        public abstract void study();
                    }

                    class PersonDemo {
                        public void method(Person p) {
                            p.study();
                        }
                    }

                    class PersonTest {
                        public static void main(String[] args) {
                            PersonDemo pd = new PersonDemo();
                            pd.method(new Person() {
                                public void study() {
                                    System.out.println("好好学习,天天向上");
                                }
                            });
                        }
                    }

            一道面试题
        interface Inter {
            void show();
        }

        class Outer {
            //补齐代码
            public static Inter method() {
                return new Inter() {

                    public void show() {
                        System.out.println("HelloWorld");
                    }   
                };
            }
        }

        class OuterDemo {
            public static void main(String[] args) {
                Outer.method().show(); //"HelloWorld"
            }
        }



    //  接口和抽象类也可以实例化。利用多态。如下:
        Inter i = new Inter() { //多态   new Inter() {...} 其实是Inter的子类实例化
            public void show() {
                System.out.println("show");
            }

            public void show2() {
                System.out.println("show2");
            }
        };
经验分享 程序员 微信小程序 职场和发展