您现在的位置是:网站首页> Android
Java学习笔记
- Android
- 2025-07-02
- 1378人已阅读
Java语法回顾
包也就是目录(import com.hello.A 相当于目录com\\hello\\A)
synchronized 是 Java 中的一个关键字,用于实现线程同步
数据类型转换
long i=122;
short c=(short)i;
一、数字转字符串
1、通过ToString() 方法, Double 就是一个包装类,String s1 = Double.toString(num);
Integer同理
2、通过valueof() 方法, 本质上还是调用 toString() 方法,String s2 = String.valueOf(num);
3、技巧性,第三种没有借助包装类 String s3 =""+num;
二、字符串转数字
string 和int之间的转换
string转换成int :Integer.valueOf("12") 或者Integer.PaseInt(“12”)
三、 char和int之间的转换
首先将char转换成string
String str=String.valueOf('2')
Integer.valueof(str) 或者Integer.parseInt(str)
Integer.valueof返回的是Integer对象,Integer.parseInt
返回的是int
类和接口
【修饰】 class 类名 【extends 父类】【implements 接口名】
{
类成员变量声明
类方法声明
}
修饰 protected 它只能被与该类处于同一个包的类或该类的子类直接存取和使用
定义了 abstract抽象方法的类必须被声明为abstract的抽象类
调用父类函数如:
public void MyFunc()
{
super.MyFunc();
...
}
调用父类的构造函数
super(a,b,c);
调用另一个构造函数
this(a,b,c);
在java这门编程语言中,final是一个关键字,它可以被用来修饰类,变量以及成员方法
被final修饰的变量,又叫被称为 自定义常量
1. final修饰类
当final关键字修饰一个类,则该类会成为最终类,即该类不能被继承(俗称“断子绝孙类”),但是该类可以有父类
//类名为Fu的类被final关键字修饰,代表其不能被继承
final class Fu {
}
//现在类名为Zi的类想继承Fu这个类,编译器会报错
class Zi extends Fu {
}
2. final修饰变量(成员变量和局部变量)
变量分为成员变量和局部变量,他们被final修饰时有不同的注意事项。
(1) final修饰成员变量:该成员变量必须在其所在类对象创建之前被初始化(且只能被初始化一次)。
这句话的意思是: 被final修饰的成员变量,一定要被赋值且只能被赋值一次,且必须是在这个成员变量所在的类对象创建之前被赋值。
试验代码:
第一种,给其直接初始化(赋值):
private final int a=5
第二种,在构造代码块中将其初始化(赋值):
private final int a;
//构造函数
{
a=5;
}
第三种,在成员变量所在类的构造方法中将其初始化(赋值):
private final int a;
public Demo(int b)
{
this.a=b;
}
总结:
final修饰成员变量,该变量必须在 其所在类对象 创建之前完成初始化且只能被初始化一次(我的理解:对象被创建,说明要使用这个对象,所以身为这个对象属性之一的成员变量就必须要被赋值)
final修饰局部变量,该变量在定义时可以不被初始化,但是使用之前,必须完成初始化且只能初始化一次!
总而言之一句话:
final修饰的成员变量在定义时必须初始化(三种方法),final修饰的局部变量定义时可以不被初始化,但是使用之前必须完成初始化!
当final修饰引用数据类型(类、接口、数组)的变量,则引用变量所指向的对象(即该变量所存放的地址值)不能更改,但是该对象的内容(即地址值上存储的内容)可以更改!!
不能改变被final修饰的引用变量所指向的对象,但是可以改变其指向对象的内容:
final修饰成员方法
当final关键字修饰了成员方法,则意味着这个方法不能被重写,但是可以被继承(注意,这里final修饰的是方法而不是类
class C{
public final void Test(){
}
}
class D extends C{
//错误会报错
public void test(){
}
}
抽象类与抽象方法
首先创建一个表示图形的抽象类 Shape,代码如下所示
public abstract class Shape {
public int width; // 几何图形的长
public int height; // 几何图形的宽
public Shape(int width, int height) {
this.width = width;
this.height = height;
}
public abstract double area(); // 定义抽象方法,计算面积
}
定义一个正方形类,该类继承自形状类 Shape,并重写了 area( ) 抽象方法。正方形类的代码如下:
public class Square extends Shape {
public Square(int width, int height) {
super(width, height);
}
// 重写父类中的抽象方法,实现计算正方形面积的功能
@Override
public double area() {
return width * height;
}
}
定义一个三角形类,该类与正方形类一样,需要继承形状类 Shape,并重写父类中的抽象方法 area()。三角形类的代码实现如下:
public class Triangle extends Shape {
public Triangle(int width, int height) {
super(width, height);
}
// 重写父类中的抽象方法,实现计算三角形面积的功能
@Override
public double area() {
return 0.5 * width * height;
}
}
最后创建一个测试类,分别创建正方形类和三角形类的对象,并调用各类中的 area() 方法,打印出不同形状的几何图形的面积。测试类的代码如下:
public class ShapeTest {
public static void main(String[] args) {
Square square = new Square(5, 4); // 创建正方形类对象
System.out.println("正方形的面积为:" + square.area());
Triangle triangle = new Triangle(2, 5); // 创建三角形类对象
System.out.println("三角形的面积为:" + triangle.area());
}
}
在该程序中,创建了 4 个类,分别为图形类 Shape、正方形类 Square、三角形类 Triangle 和测试类 ShapeTest。其中图形类 Shape 是一个抽象类,创建了两个属性,分别为图形的长度和宽度,并通过构造方法 Shape( ) 给这两个属性赋值。
在 Shape 类的最后定义了一个抽象方法 area( ),用来计算图形的面积。在这里,Shape 类只是定义了计算图形面积的方法,而对于如何计算并没有任何限制。也可以这样理解,抽象类 Shape 仅定义了子类的一般形式。
正方形类 Square 继承抽象类 Shape,并实现了抽象方法 area( )。三角形类 Triangle 的实现和正方形类相同,这里不再介绍。
在测试类 ShapeTest 的 main( ) 方法中,首先创建了正方形类和三角形类的实例化对象 square 和 triangle,然后分别调用 area( ) 方法实现了面积的计算功能。
抽象类使用注意事项
一个类如果定义为抽象类,那里面可以没有抽象方法
一个类中如果有抽象方法,那所在类必为抽象类
抽象类不能被实例化,可以实例化这个抽象类的非抽象子类,
抽象类中的所有非抽象子类必须重写抽象类中的抽象方法
抽象类中,可以有构造方法,是供给子类创建对象时,初始化父类成员使用的
抽象类中的抽象方法只是声明,不包含方法体,也就是不给出具体的实现细节
接口
public interface Shape{
public abstract double area();
public abstract double valume();
public abstract String getName();
}
public class MyClass implements Shape{
public double area()
{
return 0.0;
}
}
Java类接口例子
基类继承
public abstract class Person
{
private String name;
public Person(String n)
{
name=n;
}
public abstract String getDes();
public String getName()
{
return name;
}
}
class Student extends Person
{
public Student(String n,String m)
{
super(n);
major=m;
}
public String getDec()
{
return major;
}
private String major;
}
接口
public interface Flayable{
public final int wiNumber;
public abstract void Fly();
}
public class Bat implements Fly
{
@override
public void Fly()
{
}
}
Java泛类型
public class UHFReaderResult<T> {
/**
* 结果码类
*/
public class ResultCode{
/*
* 成功
* */
public static final int CODE_SUCCESS=0;
/*
* 失败
* */
public static final int CODE_FAILURE=1;
/*
* 未连接读写器
* */
public static final int CODE_READER_NOT_CONNECTED=2;
/*
* 打开串口失败
* */
public static final int CODE_OPEN_SERIAL_PORT_FAILURE=3;
/*
* 上电失败
* */
public static final int CODE_POWER_ON_FAILURE=4;
}
/**
* 返回的消息类
*/
public class ResultMessage{
//uhf读写器没有连接.
public static final String READER_NOT_CONNECTED="没有连接UHF模块.";
public static final String OPEN_SERIAL_PORT_FAILURE="打开串口失败.";
public static final String CODE_POWER_ON_FAILURE="模块上电失败!";
}
public UHFReaderResult(int resultCode){
this.resultCode=resultCode;
}
public UHFReaderResult(int resultCode,String message){
this.resultCode=resultCode;
this.message=message;
}
public UHFReaderResult(int resultCode,String msg,T data){
this.resultCode=resultCode;
this.message=message;
this.data=data;
}
/*
* 返回结果
* */
private int resultCode;
/*
* 返回结果
* */
private T data;
/*
* 消息
* */
private String message;
/**
* 获取结果码
*
* @return uhf操作返回的结果码,参考ResultCode里面常量值
*
* @see ResultCode
*/
public int getResultCode() {
return resultCode;
}
public void setResultCode(int resultCode) {
this.resultCode = resultCode;
}
/**
* 获取结果消息
*
* @return 结果消息
*
*/
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
/**
* 获取结果数据
*
* @return 结果数据
*
*/
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
synchronized 是 Java 中的一个关键字,用于实现线程同步
synchronized 是 Java 中的一个关键字,用于实现线程同步,确保在同一时刻只有一个线程可以执行被标记的代码块或方法。在你提供的代码中,synchronized 修饰了 connect 方法,这意味着:
1.线程互斥访问:如果多个线程同时调用同一个 UHFReader 实例的 connect 方法,它们将被强制串行执行。也就是说,当一个线程正在执行该方法时,其他线程必须等待,直到当前线程执行完毕。
2.锁的作用对象:synchronized 方法默认使用对象实例(即 this)作为锁。因此,如果有多个线程访问同一个对象的 connect 方法,它们会竞争同一把锁;但如果是不同对象的 connect 方法调用,则不会相互影响。
3.原子性保障:在多线程环境中,connect 方法内部的操作会被视为一个不可分割的原子操作,避免多个线程同时修改共享资源导致的数据不一致问题。
典型使用场景
资源独占:例如设备连接(如示例中的 UHF 阅读器连接),防止多个线程同时操作同一设备导致冲突。
初始化保护:确保对象在初始化过程中不会被其他线程干扰。
注意事项
性能影响:频繁的同步可能导致线程阻塞,降低系统吞吐量。
锁粒度:应尽量缩小同步范围(例如使用 synchronized 代码块而非整个方法)。
静态方法同步:如果 connect 是静态方法,锁对象将是类的 Class 对象(即 UHFReader.class),而非实例。
示例对比
java
// 方法级同步(使用 this 作为锁)
public synchronized UHFReaderResult<Boolean> connect(Context context) {
// 同一时刻仅允许一个线程执行此代码
}
// 等价于以下代码块同步
public UHFReaderResult<Boolean> connect(Context context) {
synchronized (this) {
// 同步代码块
}
}
如果需要更具体的解释或示例,可以提供更多上下文。
Java线程同步有哪些方法,具体介绍并给出例子
在 Java 中,线程同步是保证多线程环境下数据一致性和正确性的重要机制。以下是几种常见的线程同步方法及其示例:
1. synchronized 关键字
作用:修饰方法或代码块,确保同一时刻只有一个线程访问。
锁对象:
实例方法:锁是当前对象实例(this)。
静态方法:锁是类的Class对象(如MyClass.class)。
代码块:指定锁对象(如synchronized(obj))。
示例:
java
public class Counter {
private int count = 0;
// 方法级同步(锁为this)
public synchronized void increment() {
count++;
}
// 等价的代码块同步
public void decrement() {
synchronized (this) {
count--;
}
}
}
2. ReentrantLock 类(java.util.concurrent.locks)
作用:显式锁,功能比synchronized更灵活(可中断、可定时、公平锁)。
核心方法:
lock():获取锁。
unlock():释放锁(必须在finally块中调用)。
示例:
java
import java.util.concurrent.locks.ReentrantLock;
public class Counter {
private final ReentrantLock lock = new ReentrantLock();
private int count = 0;
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock(); // 确保锁释放
}
}
}
3. volatile 关键字
作用:保证变量的可见性(一个线程修改后,其他线程立即看到最新值),但不保证原子性。
适用场景:标记状态变量(如isRunning)。
示例:
java
public class FlagExample {
private volatile boolean isRunning = true;
public void stop() {
isRunning = false;
}
public void run() {
while (isRunning) {
// 执行任务
}
}
}
4. Atomic 原子类(java.util.concurrent.atomic)
作用:基于 CAS(Compare-and-Swap)实现无锁原子操作,性能优于synchronized。
常见类:AtomicInteger、AtomicLong、AtomicReference。
示例:
java
import java.util.concurrent.atomic.AtomicInteger;
public class Counter {
private final AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet(); // 原子自增
}
}
5. wait()、notify() 和 notifyAll()
作用:线程间通信机制,必须在synchronized块中调用。
wait():释放锁并阻塞线程。
notify():唤醒一个等待的线程。
notifyAll():唤醒所有等待的线程。
示例:生产者 - 消费者模型
java
public class MessageQueue {
private final Object lock = new Object();
private String message;
private boolean available = false;
public void produce(String msg) {
synchronized (lock) {
while (available) {
try {
lock.wait(); // 等待消费者取走消息
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
message = msg;
available = true;
lock.notifyAll(); // 通知消费者消息可用
}
}
public String consume() {
synchronized (lock) {
while (!available) {
try {
lock.wait(); // 等待生产者发送消息
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
available = false;
lock.notifyAll(); // 通知生产者可以继续生产
return message;
}
}
}
6. CountDownLatch
作用:让一个或多个线程等待其他线程完成操作后再继续执行。
核心方法:
countDown():计数器减 1。
await():阻塞直到计数器为 0。
示例:
java
import java.util.concurrent.CountDownLatch;
public class Demo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(3); // 等待3个任务
for (int i = 0; i < 3; i++) {
new Thread(() -> {
System.out.println("任务完成");
latch.countDown();
}).start();
}
latch.await(); // 主线程等待所有任务完成
System.out.println("所有任务已完成");
}
}
7. CyclicBarrier
作用:让一组线程相互等待,直到所有线程都到达某个屏障点后再继续执行。
核心方法:await()。
示例:
java
import java.util.concurrent.CyclicBarrier;
public class Demo {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("所有线程已就绪,开始执行");
});
for (int i = 0; i < 3; i++) {
new Thread(() -> {
try {
System.out.println("线程准备就绪");
barrier.await(); // 等待其他线程
System.out.println("线程开始执行");
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
}
8. Semaphore
作用:控制同时访问某个资源的线程数量。
核心方法:
acquire():获取许可(如果没有则阻塞)。
release():释放许可。
示例:限制同时访问的线程数
java
import java.util.concurrent.Semaphore;
public class ResourceAccess {
private final Semaphore semaphore = new Semaphore(2); // 允许2个线程同时访问
public void accessResource() {
try {
semaphore.acquire();
System.out.println("获取资源访问权");
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
semaphore.release();
System.out.println("释放资源访问权");
}
}
}
总结
同步方法 适用场景 特性
synchronized 简单的方法 / 代码块同步 隐式锁,自动释放
ReentrantLock 复杂场景(可中断、公平锁)显式锁,需手动释放
volatile 变量可见性 不保证原子性
Atomic 类 原子操作(如计数) 无锁,高性能
wait()/notify() 线程间协作 必须在同步块中使用
CountDownLatch 等待多个线程完成 一次性使用
CyclicBarrier 一组线程相互等待 可循环使用
Semaphore 限制并发线程数 控制许可数量
根据具体需求选择合适的同步机制,可以避免线程安全问题并提高程序性能。
上一篇:Android快速回顾