Java 零碎补充

本文介绍了Java编程的基础知识,包括cmd命令行编译时的字符编码设置,如何避免乱码;讲解了标识符、数据类型、运算符的使用,以及流程控制结构如if和switch。还深入探讨了Java中的数组、异常处理、多态、内存管理和垃圾回收。此外,文章还涉及了参数传递机制、this和super的使用,以及接口与内部类的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java 基础

cmd 命令行编译乱码问题

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

在这里插入图片描述

// 编译时指定编码方式,避免乱码
javac -encoding utf8 Hello.java

在 .java 文件所在目录,输入 cmd,即可进入当前目录,方便快捷!

在这里插入图片描述

文档注释

javadoc -encoding utf8 -version -author -d mydir Hello.java

在这里插入图片描述

标识符

字母、数字、_、$、中文(不建议用)

数据类型

char,gbk 占 2 字节,utf-83 字节
long l2 = 30000000000l; // 超过 Integer 范围,必须要后加 l/L
float f = 2.1f; // 必须带 f/F,因为默认浮点型是 double 类型的,double 不能自动转成 float
char c = 23578; // 只能赋值 [0, 65535] 范围,对应字符集编码值,如 A -> 65,a -> 97

运算符

        int i = 1;
        // (先赋值再自增)① i 赋值给 i++ ② i 自增 ③ i++ 赋值给 i
        i = i++;
        System.out.println(i);  // 10

        int j = 1;
        System.out.println(j == j++);   // true
//        j = ++(i++);    // 错误,++ 只能用于变量

        int m = 1;
        // (先自增后赋值)① m 自增 ② m 赋值给 ++m ③ ++m 赋值给 m
        m = ++m;
        
        int r = 1;
        /*
         ① r 赋值给 r++,r = 1, r++ = 1
         ② r 自增,r = 2, r++ = 1
         ③ r++ - r = 1 - 2 = -1
         ④ r 赋值给 r++, r = 2, r++ = 2
         ⑤ r 自增,r = 3, r++ = 2
         ⑥ (r++ - r) + r++ = -1 + 2 = 1 
         */
        int s = r++ - r + r++;
        System.out.println(s);  // 1
        int f = 1;
        boolean b = f > 1 & f++ > 1;    // & 不短路,&& 短路
        System.out.println(f);  // 2

System.out.println(2 > 1 ? 100 : 9.0);  // 100.0,类型提升
		short s = -32768; // 在 [-32768, 32767] 范围内,正确
//        s = s + 10;   // 类型提升至 int,编译报错
        s += 10; // 正确

输入

        Scanner scanner = new Scanner(System.in);

        int i = scanner.nextInt();
        System.out.println(i);

        // 读取上面的换行,避免之后输入不了
        scanner.nextLine();

        String s = scanner.nextLine();
        System.out.println(s);

流程控制结构

if(s > 10) int a = 10;  // Declaration not allowed here(只有一行代码,变量声明没有意义,不可能被使用)
		int i = 10;
        switch (i) {    // switch 支持 byte,short,int,char,String(JDK 1.7 新增),枚举
            case 10:
                System.out.println(10);
            case 11:
                System.out.println(11);
            case 12:
                System.out.println(12);
                break;
            default:
                System.out.println(0);
        }

        // 输出,遇到 break 或 } 执行结束
        /*
        *
        * 10
        * 11
        * 12
        *
        * */

数组

		// 二维数组 arr 各元素指向的各个一位数组相互独立
        int[][] arr = new int[][]{
                {1,2},
                {11, 22, 33}
        };

常见错误

System.out.println(null);
System.out.println(091);	// 0 开头表示八进制数,八进制数最大数字位应小于 8
int i; System.out.println(i);   // 没初始化,不允许使用

面向对象

参数传递机制内存分析

class Person {
    int id;
    String name;

    Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

public class Test {
    public static void main(String[] args) {
        Person person = new Person(1, "Tom");
        fun(person);
        System.out.println(person);
    }

    public static void fun(Person person) {
        person = new Person(2, "Jack");
        System.out.println(person);
    }
}
/*
Person{id=2, name='Jack'}
Person{id=1, name='Tom'}
*/

在这里插入图片描述

this/super

起点不同,终点相同,this 从自己开始,super 从父亲开始,没有就继续找父亲!

使用方法和属性的时候其前面都会默认带有 this.,此 this 具体指的是哪个类呢?方法看实际对象,属性来本类!

public class Test {

    static class Father {
        public String name = "Father";

        public void f() {
            // 属性看类(父类的 name)
            System.out.println("Father f() " + this.name);
            // 方法看对象(如果是 Son 调用 f(),那么此处调用的就是 Son 的 common())
            this.common();
        }

        public void common() {
            System.out.println("Father common()");
        }

    }

    static class Son extends Father {
        public String name = "Son";

        public void common() {
            System.out.println("Son common()");
        }
    }

    public static void main(String[] args) {
        Son son = new Son();
        son.f();
    }
}

/*
Father f() Father
Son common()
*/
static class Person {
        public String name = "Father";

        public Person(String name) {
            this.name = name;
            // 此时 Person 对象尚未初始化完成,其子类 Student 对象尚未初始化
            // this.f() 调用的是子类的 f(),子类的 name = null
            f();
        }

        public void f() {
            System.out.println(name);
        }

    }

    static class Student extends Person {
        private String name = "Son";

        public Student(String name) {
            super(name);
        }

        public void f() {
            System.out.println(name);
        }
    }

    public static void main(String[] args) {
        Student student = new Student("Tom");   // null
    }
static class Person {
        public String name = "Father";

        public Person(String name) {
            this.name = name;
            System.out.println("Person 构造器");
        }

    }

    static class Student extends Person {
        private String name = "Son";
        private int no;

        public Student(String name, int no) {
            // 必须在首行,调用父类的构造器,不能与 this 同时存在,不写此行代码,默认也会有 super(),
            // 也就是说默认是调用父类的无参构造器。得保证父类有对应的构造器
            super(name);
            System.out.println("Student 构造器");
        }
    }

    public static void main(String[] args) {
        Student student = new Student("Tom", 20210001);
    }

/*
Person 构造器
Student 构造器
*/

权限修饰符

本类本包其他包(子类)其他包(非子类)
public
protected×
默认××
private×××

多态

父类引用指向子类,必须调用重写方法

// 向下转型
class A {}
class B extends A {}
class C extends A {}

public class Test {

    public static void main(String[] args) {
        A a = new B();

        // 注意判断,判断运行时对象类型是否属于类
        if (a instanceof B) {
            B b = (B) a; // 向下转型
        }
        if (a instanceof C) {
            C c = (C) a; // 向下转型风险,a 只能转成 B,若不判断,会抛异常 java.lang.ClassCastException
        }
    }

}
// 多态数组
class A {}
class B extends A {}
class C extends A {}

public class Test {

    public static void main(String[] args) {
        A[] arr = new A[3];
        arr[0] = new A();
        arr[1] = new B();
        arr[2] = new C();
    }

}

Object

// 垃圾回收
class A {
    @Override
    protected void finalize() throws Throwable {
        // 回收垃圾的时候会调用这个方法
        System.out.println("A() finalize");
    }
}

public class Test {

    public static void main(String[] args) {
        A a = new A();
        // 导致刚才创建的那个 A 无处引用,成为垃圾
        a = new A();

        // 通知垃圾回收机制进行垃圾回收
        System.gc();

        try {
            Thread.sleep(2000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("finish");
    }

}

接口

interface MyInterface {
    // 静态方法(JDK 1.8 新增),只能这么调用:myInterface.staticMethod()
    public static void staticMethod() {
        System.out.println("staticMethod()");
    }
    // 通过实现类对象调用,可以被重写
    public default void defaultMethod() {
        System.out.println("defaultMethod()");
    }
}
  • 如果实现类的父类和实现的接口中有相同的方法,会调用父类的方法
  • 如果实现类的实现的多个接口中有相同的方法,实现类必须重写该方法
  • 调用实现接口的方法(接口.super.接口默认方法)

Comparable

所有用到 A 的地方,都会按照相同的排序规则,影响面大!后面的 Comparator 只影响自己一处。

class A implements Comparable<A> {
    int id;

    public A (int id) {
        this.id = id;
    }

    @Override
    public int compareTo(A o) {
        if( this == o) {
            return 0;
        }
        return this.id - o.id;  // return Integer.compare(this.id, o.id);
    }

    @Override
    public String toString() {
        return "A{" +
                "id=" + id +
                '}';
    }
}

public class Test {

    public static void main(String[] args) {
        A[] as = new A[3];
        as[0] = new A(1);
        as[1] = new A(3);
        as[2] = new A(2);

        // 调用 compareTo 进行比较、排序
        Arrays.sort(as);

        for(A a: as) {
            System.out.println(a);
        }
    }

}

Comparator

class A {
    int id;

    public A (int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "A{" +
                "id=" + id +
                '}';
    }
}

class MyComparator implements Comparator<A> {

    @Override
    public int compare(A o1, A o2) {
//        if(o1.id < o2.id) {
//            return -1;
//        } else if(o1.id > o2.id) {
//            return 1;
//        } else {
//            return 0;
//        }
        return o1.id - o2.id;
    }
}

public class Test {

    public static void main(String[] args) {
        A[] as = new A[3];
        as[0] = new A(1);
        as[1] = new A(3);
        as[2] = new A(2);

//        Arrays.sort(as, new Comparator<A>() {
//            @Override
//            public int compare(A o1, A o2) {
//                return o1.id - o2.id;
//            }
//        });

//        Arrays.sort(as, (o1, o2) -> o1.id - o2.id);

//        Arrays.sort(as, Comparator.comparingInt(o -> o.id));

        Arrays.sort(as, new MyComparator());

        for(A a: as) {
            System.out.println(a);
        }
    }

}

内部类

class Outer {
    String name = "Outer";

    class Inner {
        String name = "Inner";

        public void innerMethod() {
            System.out.println(name);   // Inner
            System.out.println(Outer.this.name);    // Outer
        }
    }
}

局部的东西不能是静态的,因为静态的是属于类的!

String

常量 + 常量,或调用 intern 方法会存入常量池中,其他都存入堆

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值