您现在的位置是:网站首页> Android

Java学习笔记

  • Android
  • 2025-07-02
  • 1378人已阅读
摘要

在线手册学习资料

Java语法回顾

数据类型转换

类和接口

抽象类与抽象方法

包也就是目录(import com.hello.A 相当于目录com\\hello\\A)

接口

Java类接口例子

Java泛类型

synchronized 是 Java 中的一个关键字,用于实现线程同步

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     限制并发线程数                            控制许可数量


根据具体需求选择合适的同步机制,可以避免线程安全问题并提高程序性能。




















Top