从0-1认识Java

简介

Java是面向对象编程。

Java语言基础包括数据类型和运算符、控制结构、数组、类和对象、异常处理、枚举和注解等;面向对象包括封装性、继承性、多态性、接口与抽象类、泛型与集合、多线程与并发编程等;

  • Java技术体系所包含的内容

  • Java语言发展状况

开发环境配置

下载JDK

下载地址 :www.oracle.com/technetwork/java/javase/downloads

  • Java术语

设置JDK

  1. 安装jdk
  2. 设置环境变量
  3. 测试:javac -version
  • JDK目录树

IDE使用

IntelliJ IDEA

新建项目
编辑区
运行

基本语法

一个简单的Java应用程序

public class FirstSample{     public static void main(String[] args)   {          System.out.println("We will not use 'Hello, World!'");     }}

注释

// 单行注释
/* * 多行注释 */
/** * 文档注释 */

Java基础知识

变量

// 变量初始化int vacationDays = 12;// 常量final double CM_PER_INCH = 2.54;

运算符

// 加减乘除+、-、*、/、+=// 取模,自增、自减%、i++、i--// 位运算符&、|、^、~// 逻辑运算符&&、||、!

数学函数

// 平方根、幂运算double y = Math.sqrt(x);double y = Math.pow(x,a);
// 三角函数Math.sinMath.cosMath.tan
// 常量Math.PIMath.E

数值类型之间的转换

强制类型转换

double x = 9.997;int nx = (int) x;

运算符优先级

类型

数据类型

整型
浮点类型
char类型
boolean类型
枚举
enum Size { SMALL, MEDIUM, LARGE, EXTRA_LARGE };

注:若整型和浮点型精度不能满足要求,BigInteger类实现了任意精度的整数运算,BigDecimal类实现了任意精度的浮点数运算。

字符串

// 定义、初始化String greeting = "Hello";// 子串String s = greeting.substring(0, 3)// 拼接:+号连接2个字符串String expletive = "Expletive";String PG13 = "deleted";String message = expletive + PG13;// 拼接:+号连接字符串与非字符串的值,后者被转化成为字符串int age = 13;String rating = "PC" + age;// 将多个字符串用一个定界符分隔:静态join()方法String all = String.join("/","S","M","L","XL");

String类对象为不可变字符串,没有提供用于修改字符串的方法,优点是:编译器可让字符串共享。

// 检测字符串是否相等s.equals(t)"Hello".equals(greeting)
API文档

https://docs.oracle.com/javase/8/docs/api/

控制流程

条件语句

Demo:

if (yourSales >= 2 * target){     performance = "Excellent";     bonus = 1000;}else if (yourSales >= 1.5 * target){     performance = "Fine";     bonus = 500;}else if (yourSales >= target){     performance = "Satisfactory";     bonus = 100;}else{     System.out.println("You're fired");}

循环

  • while循环

格式:

// 先检测循环条件while (condition) statement// 至少执行一次,再检测循环条件do statement while (condition);

Demo:

while(balance < goal){     balance += payment;     double interest = balance * interestRate / 100;     balance += interest;     years++;}
  • for循环

格式:

// for循环for(initialization; boolean_expression; update) statement// foreachfor (variable : collection) statement

Demo:

for (int i = 1; i <= 10; i++)   System.out.println(i);

Demo:遍历数组

String[] names = new String[10];for (int i = 0; i < 10; i++) names[i]="";

异常

  • Java程序运行期间可能出现的错误:
    • 文件包含了错误信息
    • 网络连接出现问题
    • 无效的数组下标
    • 使用没有被赋值的对象引用
    • ……
  • 如果出现错误而使某些操作没有完成,程序应该:
    • 返回到一种安全状态,并能够让用户执行一些其他的命令
    • 或允许用户保存所有操作的结果,并以妥善的方式终止程序

异常处理的任务:将控制权从错误产生的地方转移给能够处理这种情况的错误处理器

  • Java中的异常层次结构

抛出异常

抛出一个已经存在的异常类:

1)找到一个合适的异常类。
2)创建这个类的一个对象。
3)将对象抛出。
String readData(Scanner in) throws EOFException{    ...    while (. . .)  {           if (!in.hasNext())  { // EOF encountered            if (n < len)             throw new EOFException();      }       ...    }    return s;}

捕获异常

捕获异常:

try{      code   more code   more code}catch (ExceptionType e){     handler for this type}

捕获多个异常:

try{       code that might throw exceptions}catch (FileNotFoundException e){     emergency action for missing files}catch (UnknownHostException e){     emergency action for unknown hosts}catch (IOException e){     emergency action for all other I/O problems}

捕获后再次抛出:改变异常类型

{     access the database}catch (SQLException e){   throw new ServletException ("database error: " + e.getMessage());}

断言

作用:对条件进行检测,如果结果为false,抛出AssertionError异常。断言只应该用于在测试阶段确定程序内部的错误位置。

格式:

assert条件;assert条件:表达式;

注解

  • 注解类型
    • 内建注解
      • @Override注解:表示该方法是重写父类的某方法
      • @Deprecated注解:表示已过时
      • @SuppressWarnings注解:阻止编译器警告
    • 元注解
      • @Target注解:指定被其修饰的注解能用于修饰哪些程序元素
      • @Retention注解:描述了被其修饰的注解是否被编译器丢弃或者保留在class文件中
      • @Documented注解:指定被其修饰的注解将被JavaDoc工具提取成文档
      • @Inherited注解:指定被其修饰的注解将具有继承性
    • 自定义注解
      • 定义:public @interface AnnotationTest{}

  • 读取注解信息
java.lang.reflect包提供了对读取运行时注解的支持,通过反射获取AnnotatedElement对象,调用以下3个方法可访问注解信息:
getAnnotation():获取指定类型的注解
getAnnotations():获取所有注解
isAnnotationPresent():那段是否包含指定类型的注解
  • Demo:
public class  MyAnnotation{     //获取MyAnnotation类的getObjectInfo()方法的所有注解     Annotation[] arr=Class.forName("MyAnnotation").getMethod("getObjectInfo"). getAnnotations();     //遍历所有注解     for(Annotation an:arr){         System.out.println(an);     }}

常用操作

数据驱动测试,每种数据源适合的场景:

1)测试数据的存放:推荐使用CSV或Excel作为数据源。

2)配置数据的存放:推荐使用Properties或YAML作为数据源。

3)跨项目共享测试数据或配置数据:推荐使用数据库作为数据源。

JUnit参数化测试

  • Demo:

pom.xml:

        <dependency>            <groupId>org.junit.jupiter</groupId>            <artifactId>junit-jupiter-engine</artifactId>            <version>5.6.0</version>        </dependency>        <dependency>            <groupId>org.junit.jupiter</groupId>            <artifactId>junit-jupiter-params</artifactId>            <version>5.6.0</version>        </dependency>

代码:


import org.junit.jupiter.params.ParameterizedTest;import org.junit.jupiter.params.provider.*;import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;import static org.junit.jupiter.api.Assertions.assertNotNull;
public class LoginForJUnit {
    @ParameterizedTest    @ArgumentsSources(@ArgumentsSource(ArgumentsProviderClass.class))    void testCase_001(String url, String username, String password) throws InterruptedException {        ChromeDriver driver = new ChromeDriver();        driver.get(url);        driver.findElementByCssSelector("input[type='text']").sendKeys(username);        driver.findElementByCssSelector("input[type='password']").sendKeys(password);        driver.findElementByClassName("el-button").click();        TimeUnit.SECONDS.sleep(3);        assertEquals(username, driver.findElementByCssSelector("#nav > div:nth-child(2) > span").getText());        driver.quit();    }
    static Stream<Arguments> methodSource() {        return Stream.of(                Arguments.of("http://localhost:9002/login", "zhangsan", "zhangsan123456"),                Arguments.of("http://localhost:9002/login", "lisi", "lisi123456")        );    }
    @ParameterizedTest    @EnumSource(value = Role.class, names = {"GUEST", "USER"})    void testCase_002(Role role) {        assertNotNull(role);    }
    enum Role {GUEST, USER, ADMIN}
}

文件读写

Demo:使用CSV文件进行数据驱动测试

Github: xiaoliuzi20180524/selenium-webdriver

https://github.com/xiaoliuzi20180524/selenium-webdriver/tree/master/chapter9/src/main/java/com/data/demo
import org.testng.annotations.DataProvider;import org.testng.annotations.Test;
import java.io.BufferedReader;import java.io.FileInputStream;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;/** * @description 利用CSV文件做数据驱动测试 * @author rongrong * @version 1.0 * @date 2020/6/27 13:22 */public class TestCSVData {

    /**     * 读取csv文件     *     * @param filePath     * @return返回list集合     */    public List<Map<String, String>> getCSVData(String filePath) {        List<Map<String, String>> list = new ArrayList<Map<String, String>>();        ;        FileInputStream fileInputStream = null;        try {            fileInputStream = new FileInputStream(filePath);            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);            BufferedReader br = new BufferedReader(inputStreamReader);            //通过for循环遍历,将读取的每一行数据使用逗号进行分割并保存到map中            for (String line = br.readLine(); line != null; line = br.readLine()) {                Map<String, String> map = new HashMap<String, String>();                String key = line.split(",")[0];                String value = line.split(",")[1];                map.put("userName", key);                map.put("passWord", value);                //再将map对象放到list集合中                list.add(map);            }            br.close();        } catch (Exception e) {            e.printStackTrace();        }        return list;    }
    @DataProvider    public Object[][] testCSVData() {        //读取csv文件数据,调用getCSVData()方法来获得测试的数据        List<Map<String, String>> result = getCSVData("d:\data.csv");        Object[][] files = new Object[result.size()][];        //通过for循环遍历list,每一行的数据都会通过构造函数来进行初始化赋值        for (int i = 0; i < result.size(); i++) {            files[i] = new Object[]{result.get(i)};        }        return files;    }

    @Test(dataProvider = "testCSVData")    public void testCSVData(Map<String, String> param) {        System.out.println(param.get("userName") + "t" + param.get("passWord"));    }}

MySQL

Demo:使用数据库作为数据源

Github: xiaoliuzi20180524/selenium-webdriver

https://github.com/xiaoliuzi20180524/selenium-webdriver/tree/master/chapter9/src/main/java/com/data/demo
package com.data.demo;
import org.testng.annotations.Test;
import java.util.Map;/** * @description 读取mysql数据库 * @author rongrong * @version 1.0 * @date 2020/6/27 14:22 */public class TestDbData extends DbDataHeleper {
    @Test(dataProvider = "dbDataMethod")    public void testmethod1(Map<?, ?> param) {        System.out.println(param.get("username") + "t" + param.get("passWord") + "t" + param.get("remark"));    }}
package com.data.demo;
import org.testng.annotations.DataProvider; import java.sql.*;import java.util.*;/** * @description 读取mysql数据库 * @author rongrong * @version 1.0 * @date 2020/6/27 14:22 */public class DbDataHeleper {     static Connection conn = null;     public static String driverClassName = "com.mysql.jdbc.Driver";    public static String url = "jdbc:mysql://127.0.0.1:3306/demo?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true&zeroDateTimeBehavior=convertToNull";    public static String username = "root";    public static String password = "root";      /**     * 执行sql     *     * @param jdbcUrl 数据库配置连接     * @param sql     sql语句     * @return     */    public static List<Map<String, String>> getDataList(String jdbcUrl, String sql) {        List<Map<String, String>> paramList = new ArrayList<Map<String, String>>();        Map<String, String> param = new HashMap<String, String>();        Statement stmt = null;        try {            // 注册 JDBC 驱动            Class.forName(driverClassName);            // 打开链接            conn = DriverManager.getConnection(jdbcUrl, username, password);            // 执行查询            stmt = conn.createStatement();            ResultSet rs = null;            rs = stmt.executeQuery(sql);            String columns[] = {"username", "passWord", "remark"};            // 展开结果集数据库            while (rs.next()) {                Map<String, String> map = new LinkedHashMap<String, String>();                for (int i = 0; i < columns.length; i++) {                    String cellData = rs.getString(columns[i]);                    map.put(columns[i], cellData);                }                paramList.add(map);            }            // 完成后关闭            rs.close();            stmt.close();            conn.close();        } catch (SQLException se) {            // 处理 JDBC 错误            System.out.println("处理 JDBC 错误!");        } catch (Exception e) {            // 处理 Class.forName 错误            System.out.println("处理 Class.forName 错误");        } finally {            // 关闭资源            try {                if (stmt != null) stmt.close();                if (conn != null) conn.close();            } catch (SQLException se) {                se.printStackTrace();            }        }        return paramList;    }     @DataProvider    public Object[][] dbDataMethod() {        String sql = "SELECT * FROM `account`;";        List<Map<String, String>> result = getDataList(url, sql);        Object[][] files = new Object[result.size()][];        for (int i = 0; i < result.size(); i++) {            files[i] = new Object[]{result.get(i)};        }        return files;    }}

Redis

Demo1:jmeter中使用java获取Redis中的值

Demo2:缓存中间件Redis性能测试

场景:

(1)分别设置value值大小为64B、128B、256B、512B,往Redis集群和Redis单机写入500万条记录。

(2)并发分别设置80、160、320、500、1000、2000、3000、4000、5000、6000、8000对拥有500万条记录的Redis集群和Redis单机进行读取的测试。

集合

集合类存放于java.util包中,Java集合定义了两种基本的数据结构,一种是Collection,用来表示一组对象的集合;另一种则是Map,用来表示对象间的一系列映射或关联关系。Set、List和Queue等接口都是Collection的子接口。

Collection<E>是参数化接口,用来表示一组泛型对象的集合

ArrayList

ArrayList是Java中最常用的List实现类,通过数组实现,可存储一组不唯一、有序的对象。

特点:长度可变且可以存储任何类型的数据

优点:遍历元素和随机访问元素的效率较高

  • ArrayList常用方法

LinkedList

LinkedList使用链表结构存储数据,适合数据的动态插入和删除,但随机访问和遍历速度较慢。可作为堆栈、队列和双向队列使用。

HashSet

可存储一组唯一、无序的对象。

HashMap

Map接口存储一组成对的键(key)——值(value)对象,提供key到value的映射,通过key来检索。Map接口中的key不要求有序,不允许重复。value同样不要求有序,但允许重复。

优点:查询指定元素效率高

线程安全问题

ArrayList、LinkedList、HashSet、HashMap都是非线程安全的,在多个线程场景中使用这些基础容器会出现线程安全问题。多线程场景可考虑使用基于非阻塞算法的JUC高并发容器类。

线程不安全 高并发容器方案
ArrayList CopyOnWriteArrayList:读多写少的场景
HashSet CopyOnWriteArraySet:核心操作基于CopyOnWriteArrayList实现
TreeSet ConcurrentSkipListSet:线程安全的有序集合
HashMap ConcurrentHashMap
TreeMap ConcurrentSkipListMap

本篇文章来源于微信公众号: 海盐架构笔记



微信扫描下方的二维码阅读本文

此作者没有提供个人介绍
最后更新于 2023-06-19