Java是OOP【面向对象】的编程语言,对象的基础理解就是他有属性和方法
这个部分主要整理的笔记包括
- java编译class
- class类,类的修饰符
- 类里的方法,方法的修饰符,方法的参数,方法的返回值
- 基础数据类型,包装类
- String和stringbuffer
- arrays
- Iterator
- collection
- map
- bean对象和继承
- interface对象和继承
- 泛型
- 重载和重写和多态
- 逻辑判断
- 错误监听
java编译class
我们写的代码是java后缀的文件,但是执行代码的时候经过几个过程
- java文件的编译语法检验,写欠括号逗号是会报错的,报错会停止运行
- 把java文件编译成class后缀文件,这个class文件就是我们经常听到的jar包,工具包,我们也可以自己写一个属于自己的jar包
- 运行class文件
class类
- 类的修饰符public,有好几个修饰符,但是只要记住这个就行
创建一个java后缀的文件
// 文件地址,这个一般是开发工具自动给你带上的;
package xx.xx.A;
// 引入别的java文件
import xx.xx.B;
// 固定写法
// class的名字跟文件名字一样
// 带上public
// 一个文件只用一个class,可以用多个,但是没人这么做
// 这个理解成js里的function,模块化
public class A{
}
类里的方法
- 方法的修饰符public,固定写法
- 方法的修饰符static,加上是静态方法,不加是实例方法
public class A{
// public的class的静态属性可以被项目的任何一个地方通过【文件名.变量名】访问和修改
static String jtsx = "静态属性";
// public的class的静态属性可以被项目的任何一个地方通过【new 文件名().变量名】访问,只读
// 想要获取和修改需要通过new一个实例并且调用get和set方法,查看另一个笔记
String slsx = "实例属性";
// 执行这个文件时会自动触发的main入口方法,接入服务器后不需要,目前还是需要
public static void main(String[] args){
// 静态方法调用静态方法,如果是调用别的class,也是这样调用
A.jtff()
// 静态方法调用实例方法,如果是调用别的class,也是这样调用
A a = new A()
a.slff()
}
// 静态方法
public static void jtff(){
System.out.println(A.jtsx)
// 想要获取实例,跟main一样就行
}
// 实例方法
public void slff(){
System.out.println(this.slsx)
System.out.println(A.jtsx)
}
}
- 方法的参数,格式是数据类型加空格加参数名
// xx.java
public static void test(String str){
System.out.println(str);
}
public static void test(){
System.out.println("没有参数")
}
// 可以写同名方法,但是参数要不一样
xx.test();
xx.test("测试");
// Java static方法的参数最多只能有255个,非static方法最多只能有254个
- 方法的返回值,不返回一定要加void,返回就把void改成return的数据格式
public static String test(){
// void改成了String,不写return会报错
return "我是返回值";
}
基础数据类型
有八个,只需要记住三个
int num = 1;
double num = 1.1;
boolean flag = true;
// 包装类,虽然说Java万物皆对象,但是基础数据类型不是对象
// 这个包装类就是把基础数据类型封装成对象
// 为什么需要包装类,因为后面会学到一个东西叫集合,集合不能存基础数据类型,所以需要存包装类
// 但是不需要自己去操作,java有自动的装包拆包,这里只做了解
重载
重载就是一个类写多个同名的方法,有以下的规则
- 被重载的方法必须改变参数列表(参数个数或类型不一样);
- 被重载的方法可以改变返回类型;
- 无法以返回值类型作为重载函数的区分标准。
- 被重载的方法可以改变访问修饰符;
- 被重载的方法可以声明新的或更广的检查异常;
字符串
// 声明一个字符串
String name = "pdt1997";
// 拼接字符串
name = name + "嘻嘻嘻";
// 上面的写法最常见,但是非常的消耗内存,因为String是在创建的时候固定内存的
// 也就是说上面的代码开辟了三块内存,pdt1997,嘻嘻嘻,pdt1997嘻嘻嘻
// 所以要习惯使用StringBuffer
StringBuffer s1 = new StringBuffer().append("bbb");
s1.append("aaa");
System.out.println(s1); //bbbaaa
// 不管是那个那个创建方式,都有下面的常用方法
// length,长度
// indexof/lastIndexOf,返回位置
// reverse,反转
// insert(1, "ME") ,插入
// split,切断,支持正则
// replace(x,y,str) ,替换一个
// replaceAll("\d","**")
// Pattern.matches("^[0-9]{2}$","2223aa"); //matches 判断对不对,就是js的test
Array
Java的数组不比JS的数组,他是固定内存的,不能说添加移除的,一般用来定义固定的值比如星期一到星期天之类的,还有一个叫枚举的数据类型,跟数组一样,但是比数组更少见
int[] arr = {1,2,3,4,5,6};
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i] + " ");
}
for(int i:arr){
System.out.println(i);
}
System.out.println(arr.toString()); //toString不能少
Iterator
Iterator是一个祖宗,他有两个儿子,Collection
和Map
Collection
Collection是个爷爷,他有三个儿子,List
,Set
,Queue
,只用list就行,其他几乎不用
List
list是有序列表,也就是真正的数组,他有两个儿子,LinkedList
,ArrayList
// LinkedList:增删改快
// ArrayList:查询快(有索引的存在)增删改慢
// 这两个看着用,ArrayList比较常用,比较好记
List<String> list1 = new ArrayList<String>();//<规定数据的格式,不写就是默认什么格式都行>
list1.add("12"); // 索引位置为 0
list1.add("34"); // 索引位置为 1
list1.add("34"); // 索引位置为 1
list1.add(1,"56"); // 索引位置为 1 ,原本的1位置被挤掉
// 获取索引位置
System.out.println(list1.get(1));
// 长度
System.out.println(list1.size());
// 把第零位的内容换掉
list1.set(0,"我添加上去的");
// 查找位置
System.out.println(list1.indexOf("34"));
// 删除某个位置
list1.remove(0);
System.out.println(list1);
// 整个list清空
list1.clear();
System.out.println(list1);
// 遍历,for循环,冒号for查看数组,这里写一个jdk8.0之后才出现的方法
list.forEach( item -> { System.out.print(item+" "); });
list的流,相关资料
List<Person> list = new ArrayList<>();
list.add(new Person("jack", 60));
list.add(new Person("mike", 25));
list.add(new Person("tom", 30));
list = list.stream()
.sorted((p1, p2) -> p1.getAge() - p2.getAge())
.filter(person -> person.getAge() == 20)
.limit(1)
.skip(1)
.map(s -> s.getName().split(" "))
.collect(toList());
// 还有reduce
int sum = numbers.stream().reduce(0, (a, b) -> a + b);
// 还有最大值最小值,分组等等
Map
这个就是JS里的对象Object,这里学HashMap就行
Map<String,String> map = new HashMap<String,String>();
System.out.println("HashMap元素大小:"+map.size());
//元素添加,重名就替换
map.put("hi","hello");
map.put("my","hello");
map.put("name","hello");
map.put("is","hello");
map.put("jiaboyan","hello");
//元素获取:通过key获取value
String keyValue = map.get("jiaboyan");
//元素删除:
String value = map.remove("jiaboyan");
//清空所有元素:
map.clear();
//hashMap是否包含某个key:
boolean isContain = map.containsKey("hello");
//hashMap是否为空:
boolean isEmpty = map.isEmpty();
// 遍历,map的遍历不是遍历map,而是遍历map.entrySet()
// map.entrySet()可以用for和冒号for遍历,这里展示的是jdk8.0之后的写法
map.entrySet().forEach(
entry -> System.out.println("key:value = " + entry.getKey() + ":" + entry.getValue())
);
bean对象
// 在上一篇的类里的方法就创建过对象,也就是new 类名()
// 他实际是执行了一个我们没写的,透明的方法,我们把透明的方法显示出来
public class A{
// 构造方法
// 构造方法的名字是类的名字也是文件的名字
// 他没有返回值
// 构造函数也可以重载
public A(){
// 这个就是透明的,每个class自带的
// 每个类被实例化都是执行这个方法,相当于生命周期,如果你想在初始化一个实例时执行什么,可以在这里面写
}
}
class继承
- 子类拥有父类非 private 的属性、方法
- 继承只能单继承,不能多继承,但能多重继承
public class 父类 {
}
public class 子类 extends 父类 {
}
interface接口类
怎么理解他们存在着的意义呢,就是单纯用来被继承,限制继承,本身并没有意义
public interface Animal {
void eat();
}
接口的继承
- 可以自己添加方法,但是接口内内置的方法都需要有
- 他跟class不一样,他可以多继承
public class Cat implements Animal{
public void eat(){
System.out.println("没有这个方法会报错");
}
public void test(){
System.out.println("test");
}
}
// 接口继承接口是用 extends
public interface D extends Animal{ ... }
// 多继承
public class C implements A,B{ ... }
类可以继承接口,接口也可以继承类,可以一直得迭代上去
泛型
在list和map的笔记可以看到一个单书名号,写上类型这就是泛型,泛型用于规定数据类型,包括参数包括返回值,如果没有使用泛型就需要获取到内容后强转
// 最常使用在class和接口的封装上
public class Generic<T extends Number>{
private T key;
public Generic(T key) {
this.key = key;
}
public T getKey(){
return key;
}
}
// 上面是类上注明泛型,这个是只有某个方法注明泛型
public class Generic2{
public static <T> void say(T t){
}
}
// 使用
Generic<A> gen = new Generic()
Generic2.say() //传什么都行
重写
- 在继承的前置条件下
- 方法名、参数、返回值相同。
- 子类方法不能缩小父类方法的访问权限。
- 子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常)。
- 方法被定义为
final
不能被重写
// 普通使用方法
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗可以跑和走");
}
}
public class Test{
public static void main(String args[]){
Animal a = new Animal(); // Animal 对象
Dog b = new Dog(); // Dog 对象
a.move();// 执行 Animal 类的方法
b.move();//执行 Dog 类的方法
}
}
// super
class Cat extends Animal{
public void move(){
super.move(); // 应用super类的方法
System.out.println("猫可以跑和走");
}
}
public class Test{
public static void main(String args[]){
Cat b = new Cat(); // Cat对象
b.move(); // 两个都会执行
}
}
多态
需要继承和重写为前提
class Animal {
public void eat(){
System.out.println("吃");
};
}
class Cat extends Animal {
//覆盖父类的eat方法,就叫做重写override,也是因为有这个才有多态的特性
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
class Main {
public static void main(String[] args) {
// 向上转型,虽然还是Animal 但是执行的是被子类重写的方法
Animal a = new Cat();
a.eat(); // 调用的是 Cat 的 eat
// a.work(); // 调用的是 Animal 的 word ,但是没有这个方法
// 向下转型就是父变成某个儿子,获得儿子的功能
Cat c = (Cat)a; // 向下转型
c.work(); // 调用的是 Cat 的 work
}
}
逻辑判断
大于小于就不说话了,就是判断字符串和数字
// 判断字符串用equals,别用等于
String str = "foo";
String str1 = new String("foo");
System.out.println(str.equals(str1));
// 判断数字用等于
// isBlank判断的是空,长度为0,空白字符(包括空格,制表符 ,换行符
,换页符f,回车
)组成的字符串
StringUtils.isBlank(String str)
错误监听
- 用try-catch监听,可以多重监听
- 在类里监听
try{
// 主动抛出错误
throw new NullPointerException();
}catch(Exception e){
}finally{
// 程序代码
}
// 自定义错误类
public class myException extends Exception{ ... }
获取类
Animal an = new Animal();
// 实例的getClass方法
System.out.println(an.getClass());
其他往后看
- 反射
- 进程