Java基础(三)--常用工具类

news2025/6/9 13:37:30

文章目录

  • 第三章、常用工具类
    • 一、Java异常
      • 1、什么是异常
      • 2、异常处理
      • 3、常见的异常类型
      • 4、throws
      • 5、throw
      • 6、自定义异常
      • 7、异常链
    • 二、包装类
      • 1、包装类
      • 2、字符串与基本数据类型转换
      • 3、包装类的比较
    • 三、String 类
      • 1、创建String对象的方法
      • 2、String的常用方法
      • 3、字符串的存储
      • 4、字符串StringBuilder
        • 1)String和StringBuilder的区别:
        • 2)StringBuilder和StringBuffer
        • 3)StringBuilder类的常用方法
    • 四、集合
      • 1、List(列表)
      • 2、Set
      • 3、Map
      • 4、集合排序
        • 1)Comparator接口
        • 2)Comparable接口
        • 3)Comparable和Comparator的区别
    • 五、泛型
      • 1、为什么使用泛型
      • 2、泛型的使用
      • 3、自定义泛型类
      • 4、自定义泛型方法
    • 六、Java输入输出流
      • 1、File类
      • 2、字节流
        • 1)FileInputStream
        • 2)FileOutputStream
        • 3)缓冲流
      • 3、字符流
      • 4、对象序列化
    • 七、多线程
      • 1、什么是线程
      • 2、线程的创建
      • 3、线程的生命周期
      • 4、线程优先级
      • 5、线程同步
      • 6、线程间通信
      • 7、创建多线程的第三种方式

第三章、常用工具类

一、Java异常

1、什么是异常

在程序运行过程中,意外发生的情况,背离我们程序本身的意图的表现,都可以理解为异常。在Java中,通过Throwable及其子类描述各种不同的异常类型。
在这里插入图片描述
Throwable有两个重要的子类:Exception和Error。

Error
Error是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,表示代码运行时JVM出现的问题。
这些错误是不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。因此我们编写程序时不需要关心这类异常。

Exception
Exception是程序本身可以处理的异常。
Exception类的异常包括checked exception 和 unchecked exception。

unchecked exception
编译器不要求强制处理的异常。Java编译器不会检查这些异常,在程序中可以选择捕获处理,也可以不处理。包含RuntimeException类及其子类异常。如:NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)。

checked exception
编译器要求必须处置的异常。Java编译器会检查这些异常,当程序中可能出现这类异常时,要求必须进行异常处理,否则编译不通过。RuntimeException类及其子类以外其他Exception类的子类。如IOException、SQLException。

2、异常处理

抛出异常:
当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统处理。异常对象中包含了异常类型和异常出现时的程序状态等异常信息。运行时系统负责寻找处置异常的代码并执行。

捕获异常:
在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器。运行时系统从发生异常的方法开始,依次回查调用栈中的方法,当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适的异常处理器。若未找到合适的异常处理器,则运行时系统终止,即Java程序终止。
简单地说,异常总是先被抛出,后被捕获的。

try-catch-finally

public void method(){
	try{
		//可能产生异常的代码段
	}catch(异常类型1 ex){
		//对异常进行处理的代码段1
	}catch(异常类型2 ex){
		//对异常进行处理的代码段2
	}finally{
		//无论是否发生异常都会执行的代码段,一般释放资源的代码
	}
}

try块后可以接零个或多个catch块,如果没有catch,则必须跟一个finally块。
catch语句的顺序:先子类,后父类
发生异常时按顺序逐个匹配,只执行第一个与异常类型匹配的catch语句。

注:
1.不执行finally块的唯一情况:在finally之前中断程序,如用System.exit(1)
2.在catch 中有return关键字时先执行finally语句,再执行return语句。

3、常见的异常类型

Exception 异常层次结构的父类
ArithmeticException 算术异常
ArrayIndexOutOfBoundsException 数组下标越界异常
NullPointerException 空指针异常
ClassNotFoundException 不能加载所需的类
IIIegalArgumentException 方法接受到非法参数
ClassCastException 类型转换异常
NumberFormatException 数字格式转换异常

4、throws

如果一个方法可能会出现异常,但没有能力处理这种异常,可以在方法声明出用throws子句来声明抛出异常。throws语句用在定义方法时声明该方法要抛出的异常类型,该方法将不对这些类型及其子类类型的异常作处理,而抛向调用该方法的方法。

public void method() throws Exception1,Exception2,...ExceptionN{
	//可能产生异常的代码
}

throws的使用规则:
1、如果是不可检查异常(unchecked exception),即Error、RuntimeException或它们的子类,那么可以不使用throws关键字来声明要抛出的异常,编译仍能通过,但是运行时会被系统抛出。
2、如果一个方法中可能出现可查异常,要么用try-catch语句捕获,要么用throws子句声明将它抛出,否则编译错误。
3、当抛出了异常,则该方法的调用者必须处理货重新抛出该异常。
4、当子类重写父类抛出异常的方法时,声明的异常必须是父类方法所声明异常的同类或子类。

5、throw

throw用来抛出一个异常。
例如:throw new IOException();
throw抛出的只能是Throwable或者其子类的实例对象。抛出异常后,可以用try-catch语句捕获,也可以用throws子句声明将它抛出。

6、自定义异常

所谓自定义异常,就是定义一个类,去继承Throwable类或者它的子类。
自定义异常的常见问题:
1、自定义异常属于检查异常还是非检查异常,要看继承的父类。
2、几个异常处理的方法:
e.toString(); 获得异常类型和描述信息,当直接输出对象e时,默认调用。
e.getMessage(); 获得异常描述信息。
e.printStackTrace(); 打印出异常产生的堆栈信息,包括种类、描述信息、出错位置等。
3、自定义异常需要先经过throw抛出,才能被catch捕获,是无法自动被程序捕获并处理的。

7、异常链

捕获一个异常后再抛出另一个异常,将异常发生的原因一个传一个串起来,即把底层的异常信息传给上层,这样逐层抛出。
可以借用在异常的根类Throwable中提供的带参构造方法Throwable(String message, Throwable couse)以及初始化方法initCause(Throwable couse)实现异常链信息的传递。

二、包装类

1、包装类

基本类型对应的包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

装箱 =》基本数据类型 转换成 包装类
1、自动装箱

int t1 = 2;
Integer t2 = t1;

2、手动装箱

Integer t3 = new Integer(t1);
Integer t6 = Integer.valueOf(t1);

拆箱 =》 包装类 转换成 基本数据类型
1、自动拆箱

int t4 = t2;

2、手动拆箱

Integer t5 = t2.intValue();

注:
1、类型特点:包装类是引用类型,拥有方法和属性;基本数据类型只包含数值信息。
2、存储方式:包装类对象实例化,借由new在堆空间里进行空间分配,对象栈空间中存储地址引用;基本数据类型变量对应栈空间中存储的是具体数据值。通常,包装类的效率会比基本数据类型的效率低,空间占用大。

int one = 12;
Integer two = new Integer(20);

在这里插入图片描述
3、初始值:基本数据类型有各自默认初始值,包装类的对象未初始化时,初始值均为null。

2、字符串与基本数据类型转换

基本数据类型转字符串:
使用包装类的toString()方法

字符串转换为基本数据类型:
自动拆箱调用包装类的parseXxx()静态方法
调用包装类的valueOf()方法转换为基本类型的包装类,自动拆箱

3、包装类的比较

1、拆箱后的数据是基础数据类型。用==判断相等性,比较的都是数值,如果是字符,比较的是ASCII值。
2、装箱后如果用==比较对象的内存地址,除Double、Float外,如数据值在缓存区范围内(-128~127),则相同;反之会重新生成对象,为不同。
3、调用equals方法时,当类型相同,且数值相同时,返回true;反之,返回false。当比对方为基本数据类型时,会进行自动装箱操作,后进行比较。

三、String 类

1、创建String对象的方法

String s1 = "hello";//创建一个字符串对象hello,名为s1
String s2 = new String();//创建一个空字符串对象,名为s2
String s3 = new String("hello");//创建一个字符串对象hello,名为s3
char[] ch = {'a','b','c'};
String s4 = new String(ch);//abc
String s5 = new String(ch,1,2);//bc 1表示从第几位开始,2表示几个元素
byte[] b = [54,69,70,71,72];
String s6 = new String(b,"utf-8");

2、String的常用方法

在这里插入图片描述
注:字符串索引是从0开始的。

3、字符串的存储

在这里插入图片描述

4、字符串StringBuilder

1)String和StringBuilder的区别:

String具有不可变性,而StringBuilder不具备。

建议:
当频繁操作字符串时,使用StringBuilder。

2)StringBuilder和StringBuffer

二者基本相似

StringBuffer是线程安全的,StringBuilder则没有,所以性能略高

在执行速度方面的比较:StringBuilder > StringBuffer

3)StringBuilder类的常用方法

在这里插入图片描述

四、集合

集合框架的体系结构
在这里插入图片描述
集合和数组的区别
1、数组的长度是固定的,集合的长度可以动态扩展。
2、数组只能存储相同数据类型的数据,而集合可以存储不同数据类型的数据。
3、数组可以存储基本数据类型数据,也可以是引用类型,而集合只能是引用类型。

1、List(列表)

List是元素有序并且可以重复的集合,称为序列
List可以精确的控制每个元素的插入位置,或删除某个位置的元素
List的两个主要实现类是ArrayList和LinkedList

ArrayList
ArrayList底层是由数组实现的
动态增长,以满足应用程序的需求
在列表尾部插入或删除非常有效
更适合查找和更新元素
ArrayList中的元素可以为null

LinkedList
与 ArrayList 一样,LinkedList 也按照索引位置排序,但它的元素之间是双向链接的
适合快速地插入和删除元素
LinkedList 实现 List 和 Queue 两个接口

2、Set

Set是元素无序并且不可以重复的集合,被称为集。

HashSet
HashSet是Set的一个重要实现类,称为哈希集(底层数组+链表实现)
HashSet中的元素无序并且不可以重复
HashSet中只允许一个null元素
具有良好的存取和查找性能

Iterator(迭代器)
Iterator接口可以以统一的方式对各种集合元素进行遍历
hasNext()方法检测集合中是否还有下一个元素
next()方法返回集合中的下一个元素、

hashCode和equals方法的作用
hashCode()方法用于给对象返回hash code值,equals()方法用于判断其他对象与该对象是否相等。为什么需要这两个方法呢?我们知道HashSet中是不允许添加重复元素的,那么当调用add()方法向HashSet中添加元素时,是如何判断两个元素是不同的。这就用到了hashCode()和equals()方法。在添加数据时,会调用hashCode()方法得到hash code值,通过这个值可以找到数据存储位置,该位置可以理解成一片区域,在该区域存储的数据的hashCode值都是相等的。如果该区域已经有数据了,就继续调用equals()方法判断数据是否相等,如果相等就说明数据重复了,就不能再添加了。如果不相等,就找到一个位置进行存储。

这些是基于哈希算法完成的,它使得添加数据的效率得到了提升。假设此时Set集合中已经有100个元素,那么如果想添加第101个元素,如果此时没有使用哈希算法,就需要调用equals()方法将第101个元素与前100个元素依次进行比较,如果元素更多,比较所耗费的时间就越长。

如果两个对象相等,那么他们的hashCode值一定相等。反之,如果两个对象的hashCode值相等,那么这两个对象不一定相等,还需要使用equals()方法进行判断。

如果不重写hashCode()方法,默认每个对象的hashCode()值都不一样,所以该类的每个对象都不会相等。

3、Map

Map中的数据是以键值对(key-value)的形式存储的
key-value以Entry类型的对象实例存在
可以通过key值快速地查找value
一个映射不能包含重复的键
每个键最多只能映射到一个值

HashMap
基于哈希表的Map接口的实现
允许使用null值和null键
key值不允许重复
HashMap中的Entry对象是无序排列的

4、集合排序

使用Collections类的sort()方法
sort(List list) -根据元素的自然顺序对指定列表按升序进行排序。

1)Comparator接口

强行对某个对象进行整体排序的比较函数。
可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort)

int compare(T o1, T o2) 比较用来排序的两个参数。
– 如果o1<o2,返回负整数
– 如果o1==o2,返回0
– 如果o1>o2,返回正整数

//1.先定义比较器
public class NameComparator implements Comparator<Cat>{
	@Override
	public int compara(Cat o1, Cat o2){
		//按名字升序排序
		String name1=o1.getName();
		String name2=o2.getName();
		int n= name1.comparaTo(name2);
		return n;
	}
}
//2.调用排序
Collections.sort(catList, new NameComparator());
2)Comparable接口

此接口强行对实现它的每个类的对象进行整体排序。
这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
对于集合,通过调用Collections. sort方法进行排序。
对于数组,通过调用Arays.sort方法进行排序。

int compareTo(T o)方法
该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。

//1.定义类的时候实现Comparable接口
public class Dog implements Comparable<Dog>{
	private int age;
	...
	@Override
	public int comparaTo(Dog o){
		//按名字升序排序
		int age1=this.getAge();
		int age2=o.getAge();
		int n= age2 - age1;
		return n;
	}
}
//2.直接调用sort方法排序
Collections.sort(dogList);

注:包装类和String都有自己的comparaTo方法

3)Comparable和Comparator的区别

1、Comparator接口位于java.util包下,而Comparable接口位于java.lang包下。
2、对于Comparator接口,可以看到它的compare()方法的参数是两个对象,所以可以有一个单独的类实现Comparator。
对于Comparable接口,它的方法只有一个对象作为参数,所以要比较的类需要实现Comparable接口,将当前对象与方法参数中的对象进行比较。
因此,如果使用Comparator接口,那么要比较的类和实现Comparator接口的类可以分开,如果使用Comparable接口,那么要比较的类就要实现Comparable接口才可以。
3、关于应用场景
一般情况下如果对某个类进行排序,比如Cat类,如果使用Comparable接口的方式,那么Cat类需要实现Comparable接口。
如果Cat类通过Comparable接口的方式实现排序,比如通过name排序了。那么我们还希望通过age进行排序,这时不希望修改Cat类,那此时就需要使用Comparator接口了。
因此,Comparable接口可以作为实现类的默认排序算法,Comparator接口则用于一个类的扩展排序。

五、泛型

1、为什么使用泛型

在Java中增加泛型之前,泛型程序设计使用继承来实现的
坏处:
-需要强制转换
-可向集合中添加任意类型的对象,存在风险。

2、泛型的使用

List list = new ArrayList();
Java SE7及以后的版本中,构造方法中可以省略泛型类型。
List list=new ArrayList<>();

注: 变量声明的类型必须匹配传递给实际对象的类型
其他的错误例子:
List list=new ArrayList();
List numbers=new ArrayList();

泛型作为方法参数
<? extends Goods>表示添加的类型是Goods或子类都是允许的,extends后面的内容也可以是接口
<? super Goods> 表示添加的类型是Goods或超类都是允许的

3、自定义泛型类

public class NumGeneric<T>{
	private T num;
	//get、set...
}
NumGeneric<Integer> i = new NumGeneric<>();
i.setNum(10);
NumGeneric<Float> i = new NumGeneric<>();
i.setNum(10.5f);

4、自定义泛型方法

泛型方法不一定写在泛型类里面

public class One{
	public <T extends Number> void printV(T t){
		sout(t);
	}
}
//调用
One one = new One();
one.printV(10);
one.printV(10.5f);

六、Java输入输出流

流是指一连串流动的字符,以先进先出的方式发送信息的通道。
文件输入————读
文件输出————写

1、File类

什么是文件?
文件可认为是相关记录或放在一起的数据的集合。
在Java中,使用java.io.File类对文件进行操作。
注:
Windows中的目录分隔符为""
Linux中的目录分隔符为"/"

绝对路径:是从盘符开始的路径
相对路径:是从当前路径开始的路径

//创建file对象
File file1 = new File("c:\\abc\\a.txt");
File file2 = new File("c:\\abc","a.txt");
File file3 = new File("c:\\abc\\bcd");
File file4 = new File(file3,"a.txt");
file1.isDirectory();//是否是目录
file1.isFile();//是否是文件
file3.exists();//判断是否存在
file3.mkdir();//创建一个目录
file3.mkdirs();//创建多个目录
file4.createNewFile();//创建文件
file3.isAbsolute();//是否绝对路径
file3.getPath()//获取路径(构造方法的路径)
file3.getAbsolutePath();//获取绝对路径
file4.getName();//获取文件名

2、字节流

字节输入流InputStream
在这里插入图片描述
字节输出流OutputStream
在这里插入图片描述

1)FileInputStream

从文件系统中的某个文件中获得输入字节。
用于读取诸如图像数据之类的原始字节流。

FileInputStream常用方法
在这里插入图片描述
注:如果返回值为-1,则表示已经达到文件末尾!

2)FileOutputStream

FileOutputStream常用方法
在这里插入图片描述

//**文件拷贝小案例:**
try{
	FileInputStream fit = new FileInputStream("happy.gif");
	FileOutputStream fos = new FileOutputStream("happycopy.gif");
	int n=0;
	byte[] b = new byte[1024];
	while((n=fit.read(b))!=-1){
		fos.write(b,0,n);
	}
	fit.close();
	fos.close();
}catch(FileNotFountException e){
	e.printStackTrace();
}catch(IOException e){
	e.printStackTrace();
}
3)缓冲流

缓冲输入流BufferedInputStream
缓冲输出流BufferedOutputStream

//**文件拷贝小案例:**
try{
	FileInputStream fis = new FileInputStream("happy.gif");
	BufferedInputStream bis = new BufferedInputSream(fis);
	FileOutputStream fos = new FileOutputStream("happycopy.gif");
	BufferedOutputStream bos = new BufferedOutputSream(fos);
	int n=0;
	byte[] b = new byte[1024];
	while((n=bis.read(b))!=-1){
		bos.write(b,0,n);
		bos.flush();
	}
	fis.close();
	bis.close();
	fos.close();
	bos.close();
}catch(FileNotFountException e){
	e.printStackTrace();
}catch(IOException e){
	e.printStackTrace();
}

3、字符流

字符输入流Reader
在这里插入图片描述
字符输出流Writer
在这里插入图片描述

字节字符转换流
InputStreamReader
OutputStreamWriter

//**文件拷贝小案例:**
try{
	FileInputStream fis = new FileInputStream("happy.txt");
	InputStreamReader bis = new InputStreamReader(fis,"GBK");
	FileOutputStream fos = new FileOutputStream("happycopy.txt");
	OutputStreamWriterbos = new OutputStreamWriter(fos,"GBK");
	int n=0;
	char[] b = new char[10];
	while((n=bis.read(b))!=-1){
		bos.write(b,0,n);
		bos.flush();
	}
	fis.close();
	bis.close();
	fos.close();
	bos.close();
}catch(FileNotFountException e){
	e.printStackTrace();
}catch(IOException e){
	e.printStackTrace();
}

4、对象序列化

步骤:
-创建一个类,继承Serializable接口
-创建对象
-将对象写入文件
-从文件读取对象信息

对象输入流ObjectInputStream
对象输出流ObjectOutputStream

public class Goods implement Serializable{
	...
}
Goods goods1 = new Goods("gd001","电脑",3000);
try{
	FileOutputStream fos = new FileOutputStream("a.txt");
	ObjectOutputStream oos = new ObjectOutputStream(fos);
	FileInputStream fis = new FileInputStream("a.txt");
	ObjectInputStream ois = new ObjectInputStream(fis);
	//将Goods对象信息写入文件
	oos.writeObject(goods1);
	oos.writeBoolean(true);
	oos.flush();
	//读对象数据
	try{
		Goods goods = (Goods)ois.readObject();
		sout(goods);//输出:商品信息[编号:gd001,名称:电脑,价格:3000]
	}catch(ClassNotFoundException e){
		e.printStackTrace();
	} 
	sout(ois.readBoolean());//输出:true
	fos.close();
	oos.close();
	fis.close();
	ois.close();
}catch(FileNotFountException e){
	e.printStackTrace();
}catch(IOException e){
	e.printStackTrace();
}

七、多线程

1、什么是线程

进程:进程是指可执行程序并存放在计算机存储器的一个指令序列,它是一个动态执行的过程
线程:是比进程还要小的运行单位,一个进程包含多个线程

2、线程的创建

创建一个Thread 类,或者一个Thread 子类的对象
创建一个实现Runnable接口的类的对象
Thread类
Thread 是一个线程类,位于 java.lang 包下

构造方法:
Thread() 创建一个线程对象
Thread(String name) 创建一个具有指定名称的线程对象
Thread(Runnable target) 创建一个基于Runnable接口实现类的线程对象
Thread(Runnable target,String name) 创建一个基于Runnable接口实现类,并且具有指定名称的线程对象。

Thread类的常用方法:
public void run() 线程相关的代码写在该方法中,一般需要重写
public void start() 启动线程的方法,一个线程实例只能启动一次
public static void sleep(long m) 线程休眠m毫秒的方法
public void join() 优先执行调用join()方法的线程

class MyThread extends Thread{
	public MyThread(String name){
		super(name);
	}
	public void run(){
		sout(getName()+"该线程正常执行");
	}
}
MyThread mt1 = new MyThread("线程1");
mt1.start();
MyThread mt2 = new MyThread("线程2");
mt2.start();

Runnable接口
只有一个方法run();
Runnable 是 Java 中用以实现线程的接口
任何实现线程功能的类都必须实现该接口

为什么要实现Runnable接口?
– Java不支持多继承
– 不打算重写Thread类的其他方法

class MyRunnable implements Runnable{
	int i = 1;
	@Override
	public void run(){
		while(i<=10){
			sout(Thread.currentThread().getName()+ "正在运行"+(i++));
		}
	}
}
MyRunnable mr = new MyRunnable();
Thread t1 = new Thread(pr);
t1.start();
//MyRunnable mr1 = new MyRunnable();
Thread t2 = new Thread(pr);
t2.start();
//两个线程共享一个资源,总共打印10次

3、线程的生命周期

在这里插入图片描述
sleep方法应用
public static void sleep(long millis)
作用:在指定的毫秒数内让正在执行的线程休眠(暂停执行)
参数为休眠的时间,单位是毫秒

//在run方法里写,需要捕获异常
try{
	Thread.sleep(1000);
}catch(InterruptedException e){
	e.printStackTrace();
}

join方法应用
public final void join()
作用:等待调用该方法的线程结束后才能执行

//调用线程时执行
MyThread mt = new MyThread();
mt.start();
try{
	mt.join();
}catch(InterruptedException e){
	e.printStackTrace();
}

public final void join(long millis)
作用:等待该线程终止的最长时间为millis毫秒。
如果millis 0 为 则意味着要一直等下去。

4、线程优先级

Java为线程类提供了10个优先级
优先级可以用整数 1-10 表示,超过范围会抛出异常
主线程默认优先级为5
优先级常量
MAX_PRIORITY :线程的最高优先级 10
MIN_PRIORITY :线程的最低优先级 1
NORM_PRIORITY :线程的默认优先级 5
优先级相关的方法
public void setPriority(int newPriority) 设置线程优先级的方法,在启动线程之前执行
public int getPriority () 获取线程优先级的方法,启动线程之后执行

5、线程同步

各个线程是通过竞争 CPU 时间而获得运行机会的
各线程什么时候得到 CPU 时间,占用多久,是不可预测的
一个正在运行着的线程在什么地方被暂停是不确定的

使用关键字synchronized实现同步锁
synchronized关键字用在
– 成员方法 public synchronized void saveAccount(){}
– 静态方法 public static void saveAccount synchronized (){}
– 语句块 synchronized (obj){……}

6、线程间通信

wait()方法:中断方法的执行,使线程等待
notify()方法:唤醒处于等待的某一个线程,使其结束等待
notifyAll()方法:唤醒所有处于等待的线程,使它们结束等待

//在普通方法里写
//需要中断的时候
try{
	wait();
}catch(InterruptedException e){
	e.printStackTrace();
}
//需要唤醒的时候
notifyAll();

7、创建多线程的第三种方式

实现Calleble接口,重写call()方法,call()作为线程的执行体,具有返回值,并且可以对异常进行声明和抛出;使用start()方法来启动线程。

public class ThirdThread implements Callable<String>{
	@Override
	public String call() throws Exception {
		//方法类型可以根据要返回值的类型进行确认
		String str = "多线程的第三种创建方法";
		return str;
	}
}
Callable<String> call = new ThirdThread();
FutureTask<String> ft = new FutureTask<>(call);
Thread t3 = new Thread(ft);
t3.start();
//获取call方法的返回值:先启动线程才可以获取到Call的返回值
try{
	sout(ft.get());
}catch (InterruptedException | ExecutionException e){
	e.printStackTrace();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1592479.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

wife_wife-攻防世界

题目 注册发现可以注册管理员,但是好像有条件 抓包试试 没思路了 看看其他师傅的wp&#xff0c;用到 js 原型链污染攻击 Nodejs原型链污染攻击基础知识 | Savants Blog (lxscloud.top) 网站后端是Node.js搭建的 原型链污染 简单来讲&#xff0c;通过 newUser.__proto__ …

ssm048电子竞技管理平台的设计与实现+jsp

电子竞技管理平台设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本电子竞技管理平台就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短…

2024.4.13 Python 爬虫复习day01

目录 day01_HTTP协议HTML页面web服务器 各类名词解释 URL统一资源定位符 HTTP协议 HTML页面 知识点: 第一个页面 标题标签和图片标签 注册页面 登录页面 WEB服务器 安装fastapi和uvicorn 原始命令方式 镜像源命令方式 工具方式 快速搭建web服务器 知识点: 示例…

2024 Guitar Pro 8.1.2-27 (x64) win/mac中文激活版破解版

吉他爱好者必备神器&#xff1a;Guitar Pro v8.1.1 Build 17深度解析 随着数字音乐制作和学习的日益普及&#xff0c;越来越多的吉他爱好者开始寻找能够帮助他们提升技能、创作音乐的专业工具。在众多吉他制作软件中&#xff0c;Guitar Pro因其强大的功能和易用的界面备受推崇…

网页input框自动填充问题

autocomplete 大部分查询解决办法是设置&#xff0c;autocompleteoff&#xff0c;关于autocomplete的含义&#xff0c;官网参考如下: HTML attribute: autocomplete - HTML: HyperText Markup Language | MDN 在 autocomplete 的文档中说明了 value 为 off 时&#xff0c;浏览…

【Web】CTFSHOW-ThinkPHP5-6反序列化刷题记录(全)

目录 web611 web612 web613-622 web623 web624-626 纯记录exp&#xff0c;链子不作赘述 web611 具体分析&#xff1a; ThinkPHP-Vuln/ThinkPHP5/ThinkPHP5.1.X反序列化利用链.md at master Mochazz/ThinkPHP-Vuln GitHub 题目直接给了反序列化入口 exp: <?ph…

谷歌推出全新AI代码辅助工具Code Assist,挑战GitHub Copilot|TodayAI

在其Cloud Next大会上&#xff0c;谷歌推出了一款名为Code Assist的AI驱动代码完成工具。该工具原名为Duet AI&#xff0c;现增强了功能并与流行的编辑器兼容。 Code Assist不仅与GitHub的Copilot Enterprise直接竞争&#xff0c;还以百万级的token上下文窗口自豪&#xff0c;…

Cherno CPP学习笔记-01-背景知识

0、工具网站收集 C语言版本特性 https://en.cppreference.com https://www.cplusplus.com https://www.tutorialspoint.com/cplusplus https://www.learncpp.com https://github.com/fffaraz/awesomecpp https://stackoverflow.com 网页CPP编译器 [C] gcc 12.1.0 - Wa…

【Altium Designer 20 笔记】隐藏PCB上的信号线(连接线)

使用网络类隐藏特定类型的信号线 如果你想要隐藏特定类型的信号线&#xff08;例如电源类&#xff09;&#xff0c;你可以首先创建一个网络类。使用快捷键DC调出对象类浏览器&#xff0c;在Net Classes中右击添加类&#xff0c;并重命名&#xff08;例如为“Power”&#xff0…

Towards Street-Level Client-Independent IP Geolocation(2011年)(第二部分)

被引次数:306 Wang Y, Burgener D, Flores M, et al. Towards {Street-Level}{Client-Independent}{IP} Geolocation[C]//8th USENIX Symposium on Networked Systems Design and Implementation (NSDI 11). 2011. 接着Towards Street-Level Client-Independent IP Geolocati…

造船业的重要工具之一(火工平台)——河北北重厂家

火工平台是造船业的重要工具之一&#xff0c;它是用于火焰切割和焊接的设备。在造船过程中&#xff0c;需要对金属材料进行切割和焊接&#xff0c;以构建船体结构。火工平台可以提供高温火焰&#xff0c;使得金属材料可以被切割或焊接。 火工平台通常由两个主要部分组成&#…

【美团笔试题汇总】2024-04-13-美团春秋招笔试题-三语言题解(CPP/Python/Java)

&#x1f36d; 大家好这里是KK爱Coding &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新美团近期的春秋招笔试题汇总&#xff5e; &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f…

sql server2008触发器

sql server在Navicat工具不能插入数据 可以去写代码插入&#xff0c;代码连接sql server可以插入 或者使用sql server专门的工具 BEGINdeclare a int;declare s t_amount;select a baddebt_age_id,srate from aa_baddebt_age;INSERT INTO dade(id,name) VALUES(a,s) END

Jackson 2.x 系列【16】反序列化器 JsonDeserializer

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Jackson 版本 2.17.0 源码地址&#xff1a;https://gitee.com/pearl-organization/study-jaskson-demo 文章目录 1. 概述2. 方法2.1 构造2.2 反序列化2.3 null 处理2.4 空值2.5 其他 3. 实现类3.…

基于SpringBoot+Vue的健身器材用品网站(源码+文档+部署+讲解)

一.系统概述 随着我国经济的高速发展与人们生活水平的日益提高&#xff0c;人们对生活质量的追求也多种多样。尤其在人们生活节奏不断加快的当下&#xff0c;人们更趋向于足不出户解决各种问题&#xff0c;必录德健身器材用品网展现了其蓬勃生命力和广阔的前景。与此同时&#…

Redis中的集群(九)

集群 消息 集群中的各个节点通过发送和接收消息(message)来进行通信&#xff0c;我们称发送消息的节点为发送者(sender),接收消息 的节点成为接收者&#xff0c;如图所示。节点发送的消息主要有以下五种: 1.MEET消息:当发送者接到客户端发送的CLUSTER MEET命令时&#xff0c…

# Nacos 服务发现-快速入门-创建服务消费者模块,使用 feign 调用 服务生产者

Nacos 服务发现-快速入门-创建服务消费者模块&#xff0c;使用 feign 调用 服务生产者 1、 新增 quickstart_consumer 子工程&#xff08;子模块&#xff09;&#xff0c; 创建子模块&#xff1a;--> 右键 nacos_discovery 父工程 --> Modules --> Maven --> G…

android gradle版本无法下载

android gradle版本无法下载问题解决方法 在引入一个新的android项目的时候&#xff0c;通常会因为无法下载gradle版本而一直卡在同步界面&#xff0c;类似于下面的情况。 这是因为gradle运行时首先会检查distributionUrlhttps://services.gradle.org/distributions/gradle-5.6…

·13·1dawwd

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

lv_micropython to download and building

想要在ESP32-C3使用Micropython开发GUI&#xff0c;所以需要编译lv_micropython&#xff0c;当前github上的版本是9.1.0。 一、开发环境 因为编译lv_micropython需要在linux系统下&#xff0c;但是我的电脑是windows系统&#xff0c;所以我在windows系统上安装了VMware虚拟机&…