前言


目录标题

  • 前言
  • 学习的思维方式
  • 编码习惯
  • 地址传递与值传递
  • 特殊的String
  • next()与nextLine()区别
  • 封装
  • 继承
  • 多态
  • 关于equals()
  • 基本数据类型与包装类
  • 三元运算
  • 工具类
  • static与final
  • 接口与抽象类
  • 内部类
  • 异常
  • 多线程
  • 集合
  • HashMap
  • 反射


以下是我在学习Java基础的过程中的总结和笔记,分享给大家共同交流与进步。
框架 = 注解+反射+设计模式

学习的思维方式

1.大处着眼,小处着手
2.逆向思维、反证法
3.透过问题看本质

编码习惯

类名尽量首字母要大写 类名不分大小写 会报错

1. 如果大括号代码为空直接'{}',大括号内有代码则:左大括号左侧不换行,右侧换行;右大括号右侧换行,左侧如果不跟else等代码换行,否则不换行
 2. 小括号和字符之间不能有空格,括号内字符和运算符之间有空格 如:if (a == b)
 3. if、for、while、do、switch与括号之间必须有空格
 4. 任何二目、三目运算符前后必须有空格
 5. 采用4个空格,禁止使用tab
 6. 注释的双斜线和内容要有空格
 7. 强制类型转换时,右括号与强制转换值之间不用空格
 8. 单行字符不超过120个,超过要换行
 9. 方法在定义和传参时,必须要加空格
 10. IDE的text file encoding 设置为UTF-8;IDE中 文件的换行符使用Unix格式
 11. 单个方法尽量不超过80行
 12. 不同逻辑、不同语义、不同业务之间的代码插入一个空行分隔符

尽量避免写既有返回值,又有操作的方法,在调用进行判断时易造成二次操作

地址传递与值传递

基本数据类型:值传递

//定义
int a = 100; int b = a; b = 10;
//结果
a:100   b:10

引用数据类型:地址传递

//定义
class student{
	int a;
}
student stu = new student();
stu.a = 100;
student stu2 = stu;
stu2.a = 10;
//结果
stu.a:10  stu2.a:10

特殊的String

String类型相对特殊,虽是引用数据类型,但其数据存数在常量池中

//定义
String str1 = ("123");
String str2 = new String("123");

前者存在常量池,后者在堆中(堆中有value地址指向常量池),而且常量池中会匹配相同的(去重)
例如:

String a=“123”;和String b = “123”; 都存在于常量池中,去重,两者地址值相同,所以a==b,继而a.equals(b)为true

反例:

而String a = new String(“123”);与String b = new String(“123”);不同对象地址值不同
即a!=b 但a,equals(b)为true (String类重写了equals方法)
特别的,String a = new String(“123”);与String a = “123”;不同,但前者堆中的values地址仍指向后者

next()与nextLine()区别

首先,next()一定要读取到有效字符后才可以结束输入。
对输入有效字符之前遇到的空格键、Tab键或Enter键等结束符,next()方法会自动将其去掉,只有在输入有效字符之后, next()方法才将其后输入的空格键、Tab键或Enter键等视为分隔符或结束符。
简单地说,next()查找并返回来自此扫描器的下一个完整标记。 完整标记的前后是与分隔模式匹配的输入信息,所以next方法不能得到带空格的字符串而nextLine()方法的结束符只是Enter键, 即nextLine()方法返回的是Enter键之前的所有字符,它是可以得到带空格的字符串的。

nextLine(); 输入可以为null,以回车为结束 未避免输入前略过,需要前置一个匿名input.nextLine();(字符串任意位置都可以有空格)
next(): 必须有输入,以输入的第一个有效字符(不包括空格)为开始,直到空格键或回车键结束。(连续的字符串)
null与""不同,null未初始化

封装

java 心得 java初学心得_抽象类

继承

继承父类:可以获取父类private属性和方法,但不能直接调用 重载和重写都是早绑定,静态绑定
方法重载:方法名一致,参数列表不一致,返回值类型任意即可,重载可以在同一类中,也可在继承类中
方法重写:方法名一致,参数列表一致,返回值类型除引用类型外必须一致(void,基本数据类型),引用数据类型还可以是此类的子类 例:父Object——>子String ,权限修饰要大于等于,异常要小于等于

对属性赋值的先后顺序

1 默认初始化
2 显式赋值//代码块中赋值(看实际先后)
3 构造器赋值
4 new对象之后 通过属性方法赋值

class c{
	static {
		System.out.println("static c");//11111111111111
	}
	{
		System.out.println("非static c");//4444444444444
	}
	public c() {
		System.out.println("c");//55555555555555555
	}
}
class b extends c{
	static {
		System.out.println("static b");//2222222222222222
	}
	{
		System.out.println("非static b");//66666666666666666
	}
	public b() {
		System.out.println("b");//777777777777777777
	}
}
public class a extends b{
	static {
		System.out.println("static a");//3333333333333
	}
	{
		System.out.println("非static a");//888888888888888
	}
	public a() {
		System.out.println("a");//99999999999999999
	}
	
	public static void main(String[] args) {
		System.out.println("main()");
		new a();
	}
}

多态

多态:运行时行为,只有运行时才知道调用的时子类还是父类的方法 ,动态绑定,晚绑定,编译看左边运行看右边 Person p = new Man();

向下转型:在向上转型(多态)的基础上向下,且必须是向上转之前类或其父类 Person per = new Man();
向下转必须是小于Person大于等于Man

向上转型(多态)
转型后只能访问父类方法和子类重写的方法,不能调用子类特有的方法。
此时利用向下转型,a instanceof A判断a是否是A的一个实例,a也可以是A的子类实例,也可以是向上转型(B继承于A)

A a = new B();
System.out.println(a instanceof B);true

关于equals()

Object类中equals

public boolean equals(Object obj) {
	return (this == obj);
}

String重写了此方法

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

所以在自写类中调用equals方法需要重写来覆盖Object类中的方法。

== 只能比较基本数据类型 除boolean外 返回值为boolean

基本数据类型与包装类

基本数据类型转包装类:

int in1 = 3; Integer in2 = new Integer(in1); float double 等等

包装类转基本数据类型:

Ieteger in3 = new Integer(“123”); int in4 = in3.intValue();

**JDK5.0之后 自动装箱

int in1 = 3; Integer in2 = in1;

自动拆箱

Integer in3 = new Integer(“3”); int in4 = in3;

面试题

Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i==j);//false   new出来的地址不同
		
Integer m = 1;
Integer n = 1;
System.out.println(m==n);//true  static提前造好常用的[-128,127],不用再去new,节省内存,所以m和n地址一样
		
Integer x = 128;
Integer y = 128;
System.out.println(x==y);//false 128超出范围 所以为false

包装类其实就是把基本数据类型封装成类的属性 所以可以“.”

基本数据类型和包装类转String String.valueOf(); String转基本数据类型和包装类
Integer.parseXxx(); 除Boolean外前提时必须能转 Boolean类是除了true(不分大小写)外全是false

三元运算

Object obj = true ? new Integer(1) : new Double(2.0);
System.out.println(obj);//1.0

三元运算必须是同类型 所以int自动提升为double 而if else不会

Object obj;
if(true) {
	obj = new Integer(1);
}else {
	obj = new Double(2.0);
}
System.out.println(obj);//1

工具类

工具类:Math Arrays等都是静态类 无需new对象 直接调用

static与final

static方法里不能使用this super关键字

main方法之前先加载其父类、本类、子类中的static代码块 由父及子 new()之前先加载其父类、本类、子类中的static代码块
然后加载父类、本类(不含子类)的非static代码块、进而加载父类、本类(不含子类)的构造器 且static从头至尾只加载一次
static代码块随类加载 非static代码块随对象加载,但在构造器之前 static代码块随类的加载而执行
非static代码块随对象的创建而执行

final最终 final属性不可以初始化赋值
可以显示赋值和代码块赋值构造器赋值,构造器结束后属性就加载完毕,属性必须都有值,所以不可以方法赋值。
final修饰形参时,在方法调用时赋值,之后不可更改。 final修饰对象时 对象属性依然可以变 但对象本身不能变

接口与抽象类

抽象类:把一部分不确定的方法抽象起来 交给子类去具体实现

abstract抽象类可以修饰类和方法 不能修饰属性 构造器 也不能修饰私有方法 因为子类必须要重写 不能私有化 也不能修饰静态方法
因为static方法不算重写 也不能修饰final方法 因为不能重写 抽象类有构造器 供子类继承调用
抽象类可以没有抽象方法(通常有)但抽象方法所属的类必须为抽象类
抽象类的子类必须重写所有父类(父类的父类)的所有抽象方法,如果不,则子类也必须是抽象类,也不能实例化

抽象类:

methon(new Person()); 匿名对象new Person(); 匿名类new
Person(){重写父类(Person)的抽象方法};此时Person是抽象类,不能new 这里是省略了子类的名
用父类代替,只需把子类所需要重写的方法写上即可 匿名的作用是方便于只用一次

public class PersonTest {
	static void prt(Person per) {}
	public static void main(String[] args) {
		//非匿名对象非匿名类
		Man per = new Man();
		prt(per);
		
		//匿名对象非匿名类
		prt(new Man());
		
		//非匿名对象匿名类
		Person man = new Person() {
			@Override
			public void work() {}
		};
		prt(man);
		//匿名对象匿名类
		prt(new Person() {
			@Override
			public void work() {}
		});
	}
}

抽象类abstract和接口interface都不能实例化

类与接口呈并列关系
定义接口interface

JDK7.0及以前 只能定义全局常量和抽象方法

全局常量 (public static final) 书写时可以省略
抽象方法 (public abstract)
JDK8.0及以后 还可以定义静态方法、默认方法default 静态方法和默认方法在接口中能写方法体 实现类也可不重写 但如果实现多个接口 且接口里方法名形参都一样,则实现必须重写
一个类实现了多个接口,如果两个接口中有重复的方法名同形参 则实现类必须重写
静态方法只能接口本身用,默认方法实现类能用,可重写,可省略

接口不能定义构造器 不可实例化
接口通过类实现使用 如果实现类实现了接口中所有抽象方法 该类就可以实例化
如果没有全部实现 此类仍然是一个抽象类
类可以实现多个接口

class aa extends bb implements cc,dd,ee {}

类aa继承了bb 实现了cc,dd,ee。

接口与接口可以继承,且可以多继承
接口是一种规范,规则。
接口满足多态性

public class USBTest {
        public static void main(String[] args) {
            Computer computer = new Computer();
            computer.make(new USB() {//匿名
                @Override
                public void strat() {
                    System.out.println("Flash开始工作");
                }
                @Override
                public void stop() {
                    System.out.println("Flash停止工作");
                }
            });
            computer.make(new Printer());
        }
    }

    class Computer {
        public void make(USB usb) {
            usb.strat();
            usb.stop();
        }
    }

    class smz {
        public smz() {
            System.out.println("继承于smz");
        }
    }

    interface USB {
        void strat();
        void stop();
    }

    class Flash implements USB {
        @Override
        public void strat() {
            System.out.println("Flash开始工作");
        }
        @Override
        public void stop() {
            System.out.println("Flash停止工作");
        }
    }

    class Printer extends smz implements USB {
        @Override
        public void strat() {
            System.out.println("Printer开始工作");
        }
        @Override
        public void stop() {
            System.out.println("Printer停止工作");
        }
    }

一个类实现了接口,并继承了父类,且接口有与父类相同方法名同参数的方法,子类实现类没有重写(default),则父类方法优先调super.methon()。调接口中的方法:接口名.super.methon()

内部类

public class Superb {
        public static void main(String[] args) {
            People.Bird bird = new People.Bird();
            People people = new People();
            People.Dog dog = people.new Dog();

        }
    }
    class People {
        public void prt1() {
            System.out.println("123");
        }
        class Dog {
            public void prt2() {
                System.out.println("456");
            }
        }
        static class Bird {
            public void prt3() {
                System.out.println("789");
            }
        }
    }

内部类名字有冲突时 可用this,类名区分
局部内部类一般配合接口使用 局部内部类方法调用局部内部类所声明的方法的局部变量
要求局部变量为final

class AA {
        public void methon() {
            int num = 10;//num为final JDK8.0final已省略
            class BB {
                public void show() {
                    System.out.println(num);
                }
            }
        }
    }

    内部类在类的里面嵌套
    局部内部类在类的方法里面
    
    public class MyException extends Exception {
        static final long serialVersionUID = -1545311564145454L;

        public MyException() {}

        public MyException(String msg) {
            super(msg);
        }
    }

    public class MyExceptionTest {
        public static void main(String[] args) {
            try {
                int i = Integer.parseInt("-1");
                int j = Integer.parseInt("0");
                System.out.println(ecm(i, j));
            } catch (NumberFormatException e) {
                System.out.println("数据类型不一致");
            } catch (ArrayStoreException e) {
                System.out.println("缺少命令行参数");
            } catch (ArithmeticException e) {
                System.out.println("除〇");
            } catch (MyException e) {
                System.out.println(e.getMessage());
            }
        }
        public static int ecm(int i, int j) throws MyException {
            if (i < 0 || j < 0) {
                throw new MyException("参数小于〇");
            }
            return i / j;
        }
    }

异常

如果父类中被重写的方法没有throws处理,则子类重写的方法也不能用throws,必须用try、catch、finally

方法a中调用方法b,方法b调用方法c,递进关系使用throws抛给a,a使用try catch进行处理

方法重写后抛出的异常小于等于被重写的异常