《Java学习笔记2》

面向对象

类和对象

java实现跨平台是因为它编译为字节码之后,可以在Java虚拟机上运行,通过Java虚拟机可以编译为其他想要的编程语言,非常方便。

类:抽象出来的行为(方法) 和 特征(属性)的模板;

对象是什么:该类的具体实现,对象,看得见摸得着

类名的首字母大写,见文知意 属性名首字母小写 人: 名字 年龄 身高 性别

封装

封装的概述

  • 是指隐藏对象的属性和方法的细节,仅对外提供公共的访问方式

封装的好处

  • 隐藏实现细节,提供对外的公共的访问方式

  • 提高了代码的复用性

  • 提高了安全性

封装的原则

  • 将不需要对外提供的内容都隐藏起来

  • 把属性隐藏,提供公共方法对其访问

private关键字概述和特点

特点

  • 一个权限修饰符,本类中可用

  • 修饰成员变量和成员方法(可以)

  • 针对整个类,在方法中使用没有意义

this关键字

特点

  • 代表当前对象的引用

简单讲解

  • this应用场景:目前而言代表当前类,用来区分成员变量和局部变量

封装表现

属性私有化,公开get、set方法

方法组成

访问权限 返回值类型 方法名(参数列表)

构造方法(构造器)

作用:为属性赋初始值;

特征:

  • 1方法名与类名一致

  • 2没有返回类型

  • 3当一个类没有任何构造方法时,则系统默认给一个无参的构造方法

  • 4当一个类中有带参的构造方法,则系统默认的无参构造方法失效,想再使用,需要显式声明

static静态关键字

特点

  • 随着类的加载而加载

  • 静态优先于对象

  • 被类的所有对象共享

  • 可以用类名直接调用,也可以用对象调用

  • 静态修饰的内容我们一般称之为与类相关的,类成员

 

成员变量和静态变量的区别

1、所属不同

  • 静态变量属于类,称为类变量

  • 成员变量属于对象,可以称为对象变量

2、存储位置不同

  • 静态变量存储于方法区的静态区

  • 成员变量存储在堆内存中

3、内存出现的时间不同

  • 静态随着类的加载而加载

  • 成员变量随着对象的对象的创建而存在

4、调用不同

  • 静态可以可以被类名和对象调用

  • 成员变量只能通过对象调用

mian方法和格式

1、格式

public static void main(String[] args){
    
}

2、格式解释

  • public 被jvm调用,访问权限足够大

  • static 被jvm调用,不用创建对象,直接类名访问比较快

  • void 被jvm调用,不需要给jvm返回值

  • mian 一个通用名称,虽然不是关键字,但是被jvm识别

  • String[] args

get/set方法

  • set没有返回值

  • get有返回值

  • 要有测试类

面向对象之构造方法概述与格式

概述和作用

  • 给对象的属性值进行初始化赋值、

特点

  • 1方法名与类名一致

  • 2没有返回类型

  • 3当一个类没有任何构造方法时,则系统默认给一个无参的构造方法

  • 4当一个类中有带参的构造方法,则系统默认的无参构造方法失效,想再使用,需要重新声明

全局变量和局部变量的区别

全局变量

成员变量:全局变量==》在这个类中谁都可以用

位置:类中 方法外

生命周期:随着类的加载而加载,随着类的消失而消失·

存储位置:在堆中

初始值:可以不赋值 因为本身就有初始值

局部变量:

位置:在方法中 在方法上

生命周期:随着方法的加载而加载,随着方法的消失而消失

存储位置:在栈中

初始值:没有初始值,如果要使用必须给初始值

局部变量需要使用必须赋值才能使用。

当全局变量和局部变量相同的时候(全局和局部变量可以相同),有一个优先级关系:就近原则。

面向对象--匿名对象概述和使用

1、什么是匿名对象

大白话说:就是没有名字的对象

2、匿名对象的应用场景

  • 调用方法的时候,仅仅只能调用一次,好处:节省代码调用多次的时候,千万别用调用完就变成垃圾了,可以被垃圾回收

//例如
new Student.run();

匿名对象可以作为参数对象

//例如
public void a1(Student s){
}

创建对象的步骤逻辑

 

b/s 和c/s

b /s:浏览器服务器

c/s :客户端服务器

第一章

Java简介

查看JDK是否配置成功

cmd ->javac:出现一堆东西即配置成功 1.首先查看系统是否安装有jdk,打开cmd在DOS窗口输入 java -version查看jdk版本信息 2.你也可以输入 java -verbose查看jdk安装路径: 3.查看是否配置JAVA_HOME环境变量,输入 set JAVA_HOME,若已经配置,会出现配置路径 4.配置JAVA_HOME环境变量,输入set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_102,回车,然后,输入set JAVA_HOME查看

在cmd下运行Java源文件

  • 首先进入相应的盘

  • 然后相应的源文件路径

  • 编译源文件:javac 源文件名

  • 运行编译后的字符码文件:java 编译后字节码的源文件名,此处不用写后缀

  • 提取文档:javadoc 源文件名

第二章

8种数据类型

数据类型所占的字节(byte) {1 byte = 8 bit}
整型 byte1 范围: {-2的7次方~2的7次方}
整型 short2 范围: {-2的15次方~2的15次方}
整型 int4
整型 long8 特殊符号: 整型默认是int型所以要在数后加"L"
浮点型 float4 特殊符号: 浮点型默认是double型所以要在数后加"F"
浮点型 double8
字符型 char2
布尔型 boolean1,4,1/8

数据类型之间的优先级

很清楚啦,byte、short、char是一个级别的,它们之间的运算都会转换为int类型,注意,自己跟自己运算也会转为int类型。int之后从小到大依次为:long、float、double。至于boolean,他是个比较特殊的类型。

String不是基本数据类型,是引用类型;变量是存储数据的基本单元

变量名规则

  • 变量名前面不能是数字

  • 变量名前面可以是字母、下划线、$,其他符号不行

  • 变量明前面单词字母要小写后面单词首字母大写(标准写法)

  • 变量名后面数字也可以添加了,除了¥后面不能跟其他符号

  • 中间不可以有空格

  • 变量名不能是关键字

  • 变量得先赋值才能用

  • 避免第二个字母大写(细节)

&& 与 &的区别

  • && 条件1 && 条件2:条件1为假,条件2就不执行了(比&效率高)

  • & 不管有几个条件都走一遍(效率低)

|| 与 |的区别

  • || 条件1 || 条件2:条件1为真,条件2就不执行了(比|效率高)

  • | 不管有几个条件都走一遍(效率低)

  • 条件为真,结果为假

  • 条件为假,结果为真

第三章

while循环

//先判断后执行
while(循环的条件){
    循环体
}

do-while循环

//先执行后判断 循环一次
do{
    循环体
}while(循环的条件);//不能忘了分号

for循环

for(循环的条件){
    循环体
}

break

直接跳出整个循环体。

continue

结束本次循环过程,接着进行下一次循环过程。

if 和switch的区别:

  • if 主要针对于不确定的值

  • switch主要针对于确定的值

if-else if

区间越小的放在越上前。

第四章

数组的遍历

一维数组的增强for循环遍历方式

for(int i:array){
    System.out.println(i);
}

二维数组的增强for循环遍历方式

for(int[] i:array){//返回数据类型多加了一个中括号,遍历二位数组中一维数组
    //获得二维数组中的一维数组的地址
    for(int j:i ){//把数组里面的数遍历出来
         System.out.println(j);
    }
   
}
//如下可以输出二维表
public class Test02 {
	public static void main(String[] args) {
		int[][] arr = new int[10][10];
		arr[1][2]=11;
		arr[0][0]=11;
		for(int[] i:arr){
			for(int j:i){
				System.out.print(j+"\t");
				
			}
			System.out.println();
			
		}
	}
}

//结果
11	0	0	0	0	0	0	0	0	0	
0	0	11	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0

获取二维数组的长度的方法

  • 获取第一维数组的长度

int a = array.length;

获取第二维数组的长度的方法

int b = array[i].length;

栈、堆和方法区

详解:java存储机制(栈、堆、方法区详解)_王小的博客-CSDN博客_java堆栈方法区

堆区:

1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令) 2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身 。

栈区:

1.每个线程包含一个栈区,栈中只保存基础数据类型的值和对象以及基础数据的引用 2.每个栈中的数据(基础数据类型和对象引用)都是私有的,其他栈不能访问。 3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。

方法区:

1.又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。 2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。

继承

1、继承的格式

public class 子类 extends 父类{
    
}

2、继承的好处和弊端

  • 好处:提高了代码的复用性,提高了代码的维护性,让类与类之间产生了关系,是多态的前提

  • 弊端:类的耦合性增强了,Java的核心思想是高内聚低耦合

  • 耦合:就是类与类的关系

  • 内聚:就是自己完成某件事的能力要高

3、java中继承的特点

  • 只支持单继承,不支持多继承

  • 支持多层继承

4、Java中继承注意事项

  • 子类只能继承父类非私有成员方法及成员变量

  • 子类不能继承父类的构造方法,但是可以通过super关键字去访问父类的构造方法

  • 不要为了部分功能去继承

  • 什么时候使用继承:类A是类B的一种,或者类B是类A的一种

  • 子类中的方法的权限必须高于父类中的方法(方法名相同的时候)

  • 有同名时采用就近原则

this和super的区别

super

是子类局部范围访问父类成员变量的关键字

区别

1、调用成员变量

  • this.成员变量:可以调用本类和父类的成员变量(有同名时采用就近原则)

  • super.成员变量:调用父类的成员变量

2、调用构造方法

  • this(...) 调用本类中的构造方法

  • super(...) 调用父类中的构造方法

3、调用成员方法

  • this 可调用父类和本类中的成员方法(有同名时采用就近原则)

  • super 调用父类中的成员方法

  • super要写到方法中才能调用父类成员方法

4、继承中构造方法的关系

  • 实例化子类对象(假如是无参构造),须先执行父类构造,其次子类构造(因为子类无参构造中首行隐藏 super();)

  • 子类中super(参数);中的参数必须和父类的参数数据类型对应,其中的参数数据类型和参数名和子类本构造方法中的参数相同;

  • 有参构造中没有隐藏的super(参数),但是首行要有super(参数);

  • 如果父类没有的构造样式,子类不能有

5、静态代码块和构造代码块

  • static代码块-->构造代码块-->构造方法

  • static:父类-->子类

  • 构造代码块和构造方法(在一块),父类-->子类

方法重写

概念:

子类中出现了和父类的方法名相同,返回值必须一致

应用:

当子类需要父类的功能的时候,而功能主题特有自己的功能的时候,可以重写

方法重写注意事项

  • 父类中私有方法不能重写

  • 子类重写的方法权限要高于或等于父类中的方法

  • 父类中是静态方法必须用静态方法重写

  • 参数列表中个数相同,顺序一致,参数类型一致,返回值必须一致

Overload和Override的区别

  • Override:参数相同(范围),返回值相同,静态多态,调用的函数在编译时被选中

  • Overload: 参数不同(范围),返回不同 ,运行时是多态性的

final关键词

final修饰变量的初始化时机

  • 在对象构造完成之前完成

  • 定义变量时,修饰的变量是不可变的,变量必须给

  • 定义对象时

final Person p = new Person("张三",22);
			p = new Person("李四",21);//错误,不可改变里面的属性值
//如果要强行改变,调用set方法
			p.setName = "李四";
			p.setAge = 21;
  • 一般不定义方法,不对里面的参数起到作用

多态

1、概述

  • 事物存在的多种形态

2、前提

  • 要有继承关系

  • 要有方法重写

  • 要有父类引用指向子类对象

3、多态中成员访问特点

成员变量

  • 编译看左边,运行看左边

成员方法

  • 编译看左边,运行看右边,因为子类对该成员方法进行了重写

静态方法

  • 编译看左边,运行看左边

4、动态的好处和弊端

好处

  • 提高了代码的维护性(继承保证)

  • 提高了代码的扩展性(多态保证)

弊端

  • 不能使用子类特有的属性和行为

抽象类

格式

abstract class 类名{//抽象类
public abstract void aaa();//抽象方法
}
  • 抽象类中不一定有抽象方法

  • 在一个类中出现了抽象方法必定是一个抽象方法或者是一个接口

  • 抽象类不能实例化

  • 抽象类的子类要吗是抽象类

  • 要吗是重写抽象类中所有的抽象方法

抽象类如何实例化

  • 按照多态的方法,父类引用指向子类对象

特征

  • 抽象方法:是强制要求子类完成的

  • 非抽象方法:子类继承的事情,提高代码的复用性

接口

什么是接口

  • 侠义角度:接口就是interface

  • 广义角度:对外提供规则的都是接口

特点

  • 用关键字interface表示

  • 格式:interface + 接口名{}

  • 类实现接口 implements

  • 格式:class 类名 implements 接口名称1,接口名称2...{}

  • 接口不能实例化,要实例化就得按照多态的思想

  • 接口的子类可以是抽象类,意义不大

  • 可以是具体的实现类,重写接口中所有的抽象方法

  • 接口可以继承接口,继承的接口的所有需要被实现类实现的方法都被继承过来了

  • 接口中的成员变量永远是 public、static、final 的

  • 接口不会有构造方法

  • 默认修饰符 public、abstract\

异常

1、异常的简介

  • 运行期间发生错误,而不是编译期间发生错误

2、异常类的继承关系

  • 异常的根类:Throwable

  • 两个子类为Error、IOError(两重大错误、底层、低级的、不可恢复的严重错误)和Exception(普通异常)

  • 异常的分类

    • 检查性异

      必须写出相应的处理,否则无法运行

    • 非检查性异常

      没必要写出相应的处理,可编译运行

3、异常的处理机制

  • try{}catch(){},catch来捕获try抛出的异常

  • 有try的情况下,可以有多个catch,捕获不同类型的异常

  • Throws 异常名称,抛给下一个调用者处理

关键字finally

  1. 放在try{}catch(){}的后面

  2. finally所封装的语句,不管是否捕获成功,都是要执行的

  3. 通常是作为进行资源的清除工作

  4. 对应finally代码中的语句块,即使try{}catch(){}中使用了return、break、continue,它还是会执行,只要代码没运行到它前面退出虚拟机(System.exit(0);)它都执行。

4、自定义异常

集合

1、集合的由来

  • 数组长度的固定,当数组增加或者减少元素的时候,太麻烦了,所以Java给我们提供了集合。

  • 数组在内存中开辟等量空间,效率高,数组可以理解为无夹心的,集合可以理解为有夹心的

Collection<String> collection = new ArrayList<>();//只可以存储String类型的东西
Collection collection2 = new ArrayList();//可以存储任何类型的东西

2、迭代器

  • 迭代器的概念:查看集合元素的就叫迭代器

InteraIterator inte = collection2.iterator();
while(inte.hasNext){
    System.out.println(inte.next);
}

3、List里面的迭代器(ListIterator)

List list = new ArrayList();
		ListIterator iListIterator = list.listIterator();
		while(!iListIterator.hasNext()){
			list.add("word");
		}
  • hasNext()和hasPrevious()是一对,想要用hasPrevious(),必须先用hasNext(),涉及到指针问题,刚开始指针都指向下标0;

4、Vector

Vector v =new Vector();
v.addElement("a");
v.addElement("b");
v.addElement("c");
//迭代
Enumeration enumeration = v.elements();//Enumeration是Vector的迭代器
while (enumeration.hasMoreElements()) {
    System.out.println(enumeration.nextElement());
}

5、Set集合

1、HashSet

  • 当HashSet调用add方法存储对象的时候,先调用对象的hashcode方法得到一个哈希值,然后在集合中查找是否有和哈希值相同的对象

  • (1)如果得到一个相同的哈希值,就逐个比较,相同的抛出,不同的存入

  • (2)如果没有相同的就直接存入

2、LinkedHashSet

  • 怎么存怎么取

  • 用底层链表实现

  • 保证元素的唯一性

3、TreeSet原理

  • 特点:treeset是用来排序的,可以指定一个顺序,对象存入之后会按照顺序排序

  • 自然排序 comparable

    TreeaSet类的add方法中把存入的对象提升为comparable类型调用对象的compareTo()方法和集合中的对象进行比较,根据compareTo()方法返回的结果进行存储

  • 比较器顺序 comparator

    创建treeSet 的时候可以制定一个comparator,如果传入了comparator子类对象,那么treeSet就会按照比较器的顺序排序,add()会自定调用comparator中的compare()方法排序,调用的对象是compare方法的第一个参数,集合中的对象是第二个参数。

  • 区别

    TreeSet构造函数什么都不传,按照默认类中的comparable的顺序

    TreeSet如果传入comparator,就会先安装comparator

6、Map

package Demo_Map;

import java.util.HashMap;
import java.util.Map;

public class MyMap {
    public static void main(String[] args) {
        Map myMap = new HashMap();
        System.out.println(myMap.put(1,"hello"));
        myMap.put(2,"hi~");
        System.out.println(myMap.put(1,"world"));
        System.out.println(myMap.containsKey(1));
        System.out.println(myMap.containsKey("hello"));
        System.out.println(myMap.isEmpty());
        System.out.println(myMap.entrySet());
        System.out.println(myMap.values());
        System.out.println(myMap.keySet());
        System.out.println(myMap.get(2));
    }
}

//运行结果
null
hello
true
false
false
[1=world, 2=hi~]
[world, hi~]
[1, 2]
hi~

Map的遍历

package Demo_Map;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class MyMap {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("张三",12);
        map.put("李三",12);
        map.put("王三",12);
        map.put("奥三",12);
        map.put("常三",12);
        Set<String> keyset = map.keySet();
        Iterator<String> it = keyset.iterator();
        while (it.hasNext()){
            String key = it.next();
            Integer value = map.get(key);	
            System.out.println("key:"+key+"-->value:"+value);
        }
        Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
        Iterator<Map.Entry<String,Integer>> iterator = entrySet.iterator();
        while(iterator.hasNext()){
            Map.Entry<String,Integer> en = iterator.next();
            String str = en.getKey();
            Integer num = en.getValue();
            System.out.println("str:"+str+"num:"+num);
        }

    }
}
//结果
key:王三-->value:12
key:张三-->value:12
key:李三-->value:12
key:常三-->value:12
key:奥三-->value:12
str:王三num:12
str:张三num:12
str:李三num:12
str:常三num:12
str:奥三num:12

基本类型包装类

1、为什么会有基本数据类型包装类

  • 将基本数据类型包装成对象的好处可以在对象中定义更多的功能,这些功能或者是方法可以操作数据

2、常用的操作

  • 用于基本数据类型与字符串之间的转换

3、 基本数据类型对应的包装类

基本数据类型包装类
byteByte
shortShort
intInteger
doubleDouble
longLong
floatFloat
charCharacter
booleanBoolean
  • Integer构造器可以放String类型的数据,但是得是数字型的数字

泛型

1、好处

  • 提高安全性

  • 省去了强转

2、泛型的基本使用

  • <>里面的类型必须是引用数据类型

  • 前后反省必须一致,后面的泛型可以不写内容,自动跟前面一致

3、泛型通配符

  • <?>

  • ? extends E,向下限定,E 及其子类

  • ? super E,向上限定,E 及其父类

设计模式

装饰设计模式

  • 接口

package Demo_shejimoshi;

public interface Coder {
    public void code();
}
  • Student类

package Demo_shejimoshi;

public class Student implements Coder{
    @Override
    public void code() {
        System.out.println("发现能力不足以找工作");
    }
}
  • TengtaiStudent类

package Demo_shejimoshi;

public class TengTaiStudent implements Coder{
    /*
    获取被装饰的引用
     */
    private Student s;
    public TengTaiStudent(Student s){
        this.s = s;
    }
    @Override
    public void code() {
        s.code();
        System.out.println("来滕泰学习来咯");
    }
}
/

线程

1、什么是线程?

  • 线程是程序的一个执行的路径,一个进程包含多个线程,多线程并发执行,提高程序的效率,可以同时完成多项工作,

2、多线程并行和并发

  • 并行:两个任务同时进行,就是甲任务运行时,乙任务也在运行

  • 并发:两个任务都请求运行,处理器只能接受一个任务,就把两个任务安排轮流执行,cpu效率高间隔断,使人感觉不到切换,以为两个任务都在运行。

3、Java运行程序的原理和JVM的启动是多线程吗?

  • 原理:Java命令会启动虚拟机,等于说启动了一个应用程序,也就是启动了一个进程,该进程会自动启动一个主线程,然后主线程去调用某个类的main方法。

  • jvm启动是的多线程吗:启动至少启动了垃圾回收的一个线程、主线程,所以是多线程。

4、线程应用实现方式

thread类

  • 定义类继承Thread

  • 重写run方法

  • 在里面写要实现的东西

  • 创建线程对象

  • 开启新线程.start();内部会自动执行run方法

  • 好处:可以直接使用里面的方法,代码简单

  • 弊端:如果有父类就不能用

//主线程和myTread的线程回会互抢着运行
package Demo_Throw;
public class Demo1 {
    public static void main(String[] args) {
        myTread myTread = new myTread();
        myTread.start();
        for (int i = 0;i<3000;i++){
            System.out.println("bbb");
        }
    }
}
class myTread extends Thread{
    @Override
    public void run() {
        for (int i = 0;i<3000;i++){
            System.out.println("aaa");
        }
    }
}

Runnable接口

  • 定义实现类实现接口

  • 实现run方法

  • 把新线程要做的是写在run方法中

  • 创建自定义的runnable的子类对象

  • 创建一个Thread对象传入Runnable

  • 开启线程.start();会自动执行run方法

  • 好处:有父类也能用

  • 弊端:不能直接使用Thread类中的方法,比较复杂

package Demo_Throw;
public class MyRunnable implements Runnable{
    public static void main(String[] args) {
        MyRunnable myRunnable  = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();
        for (int i = 0;i<10000;i++){
            System.out.println("aaaaaaaaa");
        }
    }
    @Override
    public void run() {
        for (int i = 0;i<10000;i++){
            System.out.println("bbbbbbbb");
        }
    }
}

5、匿名内部类实现线程的方式

package Demo_Throw;

public class Demo2 {
    public static void main(String[] args) {
        //1、继承Thread类
        new Thread(){
            @Override
            public void run() {
              for (int i = 0;i<10000;i++){
                  System.out.println("aaaaa");
              }
            }
        }.start();
        //2、实现Runnable接口
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0;i<10000;i++){
                    System.out.println("bbbbb");
                }
            }
        }).start();
    }
}

6、获取名字和设置名字

获取名字

  • 通过getName()方法获取线程的名字,默认从0到1命名

设置名字

  • 通过构造函数传入String类型的名字

  • 通过setName()方法设置名字

7、获取当前线程的对象

currentThread();//获取当前正在所执行的线程对象的引用

8、休眠线程

Thread.sleep(毫秒);//控制当前线程休眠多少毫秒

 new Thread(){
            @Override
            public void run() {
                this.setName("渣渣辉");
                for (int i = 0;i<10;i++){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                  System.out.println("aaaaa");
              }
            }
        }.start();

9、守护线程

对象.setDaemon(true or false);//设置指定线程方法


package Demo_Throw;

import java.io.IOException;

public class Demo2 {
    public static void main(String[] args) throws IOException {
        Thread t1 = new Thread(){
            @Override
            public void run() {
                this.setName("渣渣辉");
                for (int i = 0;i<2;i++) {
                    System.out.println("aaaaa");
                }
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run() {
                this.setName("张学友");
                for (int i = 0;i<10;i++) {
                    System.out.println("bbbbb");
                }
            }
        };
        t1.setDaemon(true);
        t1.start();
        t2.start();

    }
}

10、加入线程

  • join():当前线程暂停,等待指定线程执行后当前线程再继续

  • join(int ):等待指定毫秒后再继续

package Demo_Throw;

public class Demo3 {
    public static void main(String[] args) {
        Thread t1 = new Thread(){
            @Override
            public void run() {
                for (int i = 0;i<10;i++){
                    System.out.println("aaa");
                }
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run() {
                for (int i = 0;i<100;i++){
                    try {
                        if(i == 5){
                            t1.join();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("bb");
                }
            }
        };
        t1.start();
        t2.start();
    }
}

11、设置线程的优先级

 对象.setPriority(1);//设置优先级,开发时候不要用这种方法,不好使,用if-else

12、同步代码块

  • 关键字:synchronzed加上一个锁对象来定义一段代码,这就叫同步代码块。

  • 多个代码块如果使用相同的锁对象,那么他们就是同步的

package Demo_Throw;

public class Demo4 {
    Demo3 dd = new Demo3();
    public void print(){
       synchronized (dd) {//dd为对象锁芯,如果要用当前对象为锁芯的话,dd用this,如果当前有多个对象的话,用当前类.class
            //当前类.class表示加载一次,如果有多个对象用this的话会加载多次
            //而且当方法为静态的,不能用this因为static优先于对象
            //方法为静态时候相当于上锁了	
            System.out.println("你好");
            System.out.println("你好");
            System.out.println("你好");
            System.out.println("你好");
            System.out.println("\r\n");
        }
    }
    public void print1(){
        synchronized (dd) {
            System.out.println("再见");
            System.out.println("再见");
            System.out.println("再见");
            System.out.println("\r\n");
        }
    }
    public static void main(String[] args) {
           final Demo4 demo4 = new Demo4();
           new Thread(){
               @Override
               public void run() {
                   while(true){
                       demo4.print();
                   }
               }
           }.start();
           new Thread(){
               @Override
               public void run() {
                   while(true){
                       demo4.print1();
                   }
               }
           }.start();

    }

}
//输出的时候一个锁一个锁的来,没有锁的话会抢着来

//方法同步时
package Demo_Throw;

public class Demo4 {
    Demo3 dd = new Demo3();
    public static void print(){

            System.out.println("你好");
            System.out.println("你好");
            System.out.println("你好");
            System.out.println("你好");
            System.out.println("\r\n");
    }
    public static void print1(){

            System.out.println("再见");
            System.out.println("再见");
            System.out.println("再见");
            System.out.println("\r\n");

    }
    public static void main(String[] args) {
           final Demo4 demo4 = new Demo4();
           new Thread(){
               @Override
               public void run() {
                   while(true){
                       demo4.print();
                   }
               }
           }.start();
           new Thread(){
               @Override
               public void run() {
                   while(true){
                       demo4.print1();
                   }
               }
           }.start();

    }

}

13、线程安全问题

举例:卖火车票,4个窗口,100张票

//继承Thread类
package Demo_Throw;
public class Demo5 extends Thread{
    private static int ticket = 100;
    public void run(){
        while(true){
            synchronized (Demo5.class){//
                if(ticket == 0){
                    break;
                }
                System.out.println("这是第"+ticket--+"张票");
            }
        }
    }
    public static void main(String[] args) {
        new Demo5().start();
        new Demo5().start();
        new Demo5().start();
        new Demo5().start();

    }
}

//另一
package Demo_Throw;

public class Demo5 extends Thread{
    private static int ticket = 100;
    public void run(){
        while (true) {
            buy();
            if (ticket <= 0){
                break;
            }
        }
    }

    public static synchronized void buy(){//this-->类.class
            if (ticket >= 0) {
                System.out.println("这是第:" + ticket-- + "张票");
            }
    }
    public static void main(String[] args) {
        new Demo5().start();
        new Demo5().start();
        new Demo5().start();
        new Demo5().start();

    }
}


//实现Runnable接口
package Demo_Throw;

public class Demo5 implements Runnable{
    private static int ticket = 100;
    public void run(){
        while (true) {//while写在锁外面,避免死锁
            buy();
            if (ticket <= 0){
                break;
            }
        }
    }

    public static synchronized void buy(){//this-->类.class
            if (ticket >= 0) {
                System.out.println("这是第:" + ticket-- + "张票");
            }
    }
    public static void main(String[] args) {
        Demo5 demo5 = new Demo5();
        new Thread(demo5).start();
        new Thread(demo5).start();
        new Thread(demo5).start();
        new Thread(demo5).start();

    }
}

14、死锁

  • 不能用锁去嵌套锁

反射

  • 通过类名获取该类的属性和方法、构造方法等

  • 动态地获取类的信息

  • 运行的时候,获取类的对象信息并创建对象,调用方法

  • class类型:java.lang.Class

  • JVM运行的时候,把类加载到内存中,同时会创建这个类的Class类型的对象

  • 该类封装了所有类的信息,包括属性方法、构造方法等

  • 通过getXxx获取该Class类型对象的封装信息

//Computer类
package Demo_File1;
public class Computer {
    public String name;
    private String logo;
    private String color;
    private double price;

}


//获取Computer类的属性、方法
package Demo_File1;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestClass {
    public static void main(String[] args) throws ClassNotFoundException {
        //获取class类型的对象
        //1、类名.class
        Class c1 = Computer.class;
        //Class.forName("类的路径")
        Class c2 = Class.forName("Demo_File1.Computer");
        //3、对象
        Computer computer = new Computer();
        Class c3 = computer.getClass();
        //Filed成员变量
        //获取成员变量
        Field[] arrFs = c1.getFields();//获取公有成员变量
        for(Field f:arrFs){
            System.out.println(f.getName());
        }
        //获取属性
        Field[] arrFD = c2.getDeclaredFields();//获取属性
        for(Field f1:arrFD){
            f1.setAccessible(true);
            System.out.println(f1);
            System.out.println(f1.getName());
        }
        //获取方法
        Method[] arrM = c3.getMethods();
        for (Method m:arrM){
            System.out.println(m.getName());
        }
        //获取构造方法
        Constructor[] arrC = c1.getConstructors();
        for(Constructor c:arrC){
            System.out.println(c.getName());
        }
        //获取内部类
        Class<?>[] arrInnerClass = c2.getDeclaredClasses();
        for(Class<?> c:arrInnerClass){
            System.out.println(c.getName());
        }
        //获取接口
        Class<?>[] arrInnerfaces = c3.getInterfaces();
        for(Class<?> c:arrInnerClass){
            System.out.println(c.getName());
        }
    }
}

创建对象

package Demo_File1;

public class TestNewInstance {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        //newInstance 创建对象
        Class c = null;
        c = Class.forName("Demo_File1.Computer");
        Computer computer = (Computer) c.newInstance();//调用无参构造方法,创建之后就可以调用属性和方法了
        /*
        new 和 newInstance的区别
        new可以调用有参和无参构造,强类型,效率高,可以调用任何public修饰的构造方法
        newInstance调用无参构造,弱类型,效率低
         */
    }
}

javabean

  • 类中没有业务逻辑,类处理对象,进行封装

    1. 属性私有

    2. 有无参public修饰的构造方法

    3. 私有属性提供setter、getter方法

  • getXxx首字母大写,没有返回值

  • vo model pojo entity等

Inspector(内省机制)

  • 内省机制就是通过getXxx、setXxx方法来判断Xxx是一个属性,内省机制会把Xxx的首字母变小写xxx

数据库链接步骤

  • 1.加载驱动类

Class.forName(类的路径)

导入外部jar包

  • 2.获取连接通道

DrvierManager.getConnection

url ip地址 端口号 数据库名字 3306 1521

user 用户名

password

  • 3.创建载体

Statement

PreparedStatement extends Statement

预编译 效率高 防止sql注入

setInt(1,empno)

  • 4.执行指令

executeUpdate

executeQuery ResultSet rs.next

getString(列名)

  • 5.关闭资源

 rs.close

 pst.close
 conn.close
 //获取链接通道
    public static Connection getConnection(){
        Connection conn = null;
        String url = "jdbc:oracle:thin:@localhost:1521:orcl";
//        String url = "jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true";
        String user = "scott";
        String password = "tiger";
//          String user = "root";
//          String password = "123456";
        //1、加载驱动类
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
//            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(url,user,password);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }catch (SQLException e1){
            e1.printStackTrace();
        }
        return conn;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值