1_java语法入门

background

这一章节我们学习java的一些基本使用方式和原理。 其实大部分基础语法可以不用学习, 但是对于java的注解和反射这些高级用法一定要了解, 不然后面学习一些java的框架会感觉无从下手, 只要是无从下手, 主要就是因为太难了。

content

基本的认知

  1. java的优势很大的: 很多人因为java配置繁琐等等原因讨厌这门语言, 但是在我最近看一些java评价中, 发现这门语言有一种深刻的用短期利益去换长期利益的思想。 例如一个文件只能存在一个公共类, 各种web项目的设计规则, 去掉多继承等等。 你会发现java这门语言的很多规则都是为了当项目十分大的情况下也能开发下去而考虑的, 当我们面对一个复杂的c或者python程序, 往往能看到非常多难以理解的代码, 也就是屎山, 但是java的一些规则会避免这些问题出现, 从而让代码量上来的时候也好维护。 因此不用还没学就开始讨厌这门语言。
  2. 其实很多语言都是相同的, 基本的数据结构和控制语句实现都是一样, 只需要关注一些特别的地方就行。例如java的注解等等。

语法

基本数据结构

由于java是纯面向对象的语言, 因此要一直有对象的这个概念。 我们可以看如下的一个代码, 基本数据结构都是和c++差不多的, 但是需要注意数组访问是[] 放在前面去先解释的。 此外final = const 也是常识。 还需要注意的就是var = auto.

public class ok {


    public static void main(String[] args) {
        int x = 100;
        String a = "nihao";
        var b = "nihao" ;
        System.out.println(x);
        System.out.println(a);
        System.out.println(b);
        System.out.println("hello world ");

        int y = 6;
        int sum = x + y;
        String C = a + b  + '!';
        System.out.println(C);

        int[] number = new int[]{1,23,4,5,6};  // this is equal int[] number = {1,23,4,5,6};
        System.out.println("number 0 is "+ number[0]);
        System.out.println("number length is "+ number.length);

    }
}

基本的遍历和数组操作

我们再对这个语言进行一些流程控制操作, 发现基本没啥区别。

import java.util.Scanner;

public class ok {


    public static void main(String[] args) {
        int x = 100;
        Scanner in = new Scanner(System.in);
        String name = in.nextLine();
        int age = in.nextInt();
        System.out.printf("%s,  age is %d\n", name, age);
        if (age > 18) {
            System.out.printf("adult");
        } else {
            System.out.printf("children");
        }
        int a = 0;
        while (a < 100) {
            a++;
            System.out.println(a);
        }
        for (int i = 0; i < 10; i++) {
            a++;
            System.out.println(a);
            if (a  == 105) {
                break;
            }
        }

        int[] arr =  {1,23,2,45,35,4,54};
        for (int n  : arr) {
            System.out.println(n);
        }

        int[][] arr2 = {{1,2}, {2,3}};
        for(int[] xx : arr2) {
            for(int aa : xx) {
                System.out.println(aa);
            }
        }
        System.out.print(args);

    }
}







高级的语法

  1. 理解多态:关于面向对象的编码, 需要知道多态是为了当写一个多变的业务处理函数时, 对要处理的数据搞成多态类, 自己的处理函数就可以直接抽象的处理基类就行, 具体每个基类指针指向的实际类的业务怎么写无所谓, 这大大的解耦了。

  2. 接口和静态方法 : 需要注意java中定义好了一些面向对象的设计规则, 例如接口是完全无字段的纯抽象类,但是一般里面会有一些静态字段和函数用来统计整个类的实例情况等, 主要还是工具类。

  3. 包 : 包就是类似命名空间,一个包需要按照src等方式将若干个class文件进行编译, 然后将可执行的class文件等也按照目录去放好。 这样每个源码中包含若干个包, 每个包里面有自己的类, 这些类可能和其他的包中类重名, 但是没关系。 注意如果实现一个类没有给出他的包名, 默认是公共的包里面。一般我们创建一个对象, 这个对象类会先从lang、当前package和import的包中找类。 注意一般*代表这个包中的类全部导出, 慎用。

// Main.java
package test;
import java.text.Format;
public class Main {
    public static void main(String[] args) {
        java.util.List list; // ok,使用完整类名 -> java.util.List
        Format format = null; // ok,使用import的类 -> java.text.Format
        String s = "hi"; // ok,使用java.lang包的String -> java.lang.String
        System.out.println(s); // ok,使用java.lang包的System -> java.lang.System
        MessageFormat mf = null; // 编译错误:无法找到MessageFormat: MessageFormat cannot be resolved to a type
    }
}

这时候我们还要知道jar包作用就是将多个package全部集合起来, 将jar包发送给别人。 因此我们可以说包是多个类, jar包是多个包。 当你导入别人jar包, 然后添加classpath, 自己调用class的时候JVM会去搜的。一般maven会帮你自动添加。

  1. 模块 : 我们知道大型的项目打包成jar其实会依赖很多其他的第三方jar包, 但是这样很容易漏掉这些依赖。 因此将一堆calss打包是jar, 但是如果将一堆class给出依赖关系后再打包,就是模块了。 大致意思就是jre打包项目会带很多标准class, 但是我们其实只用了一部分, 设置好依赖关系后, 我们可以从官方rt.jar中导出多个.jmod模块, 然后自己的jmod模块只需要链接自己依赖的公共的jmod就可以组成自己的jre可执行文件, 直接进行运行。

java的核心类

·1. String : 对于String是一个数值不可变的对象, 内容用final申明, 对它进行修改后是返回新的字符串对象的。 他提供了很多方法来提取搜索子串。 StringBuilder类是String的升级版本, 这样对字符串操作时候不会重新创建字符串对象, 而是通过缓存区直接在原来数据后面添加。 StringJoiner也是一个高效的string操作类。
2. 包装类型: 主要就是将基本的int等搞成类形式,例如 int i = 100; Interger n = new interger(i); 这些包装的const类会给基本类型提供多种类方法去操作, 从而拜托基本类型操作复杂的烦恼。

  1. javaBean是一个类的规范,意思是有属性的读写函数的类可以称为javaBean, 可以使用IDE自动快速生成。
  2. 还有一些常用的工具类, 例如math。

异常处理

  1. 异常处理是为了系统发生未知错误时候不要直接崩溃, 而是处理完这个异常继续运行。 常见的例子如下, 我们还可以给出一个finally给出必须要执行的部分。 此外还要注意异常的顺序, 有些异常先处理了可能会导致后面其他的异常不被执行, 需要按照异常的大小来写catch。 我们需要注意常见的异常有一些文件和数据类型错误的, 有些需要我们自己throw, 但是有些会自动抛出常见的异常。
    public static void main(String[] args) {

        try {
            System.out.println("dadads");

            NullPointerException e  = new NullPointerException();
            throw e;

        } catch (NullPointerException e) {
            System.out.println("error");
        } finally {
            System.out.println("end");
        }

    }
}

  1. assert是一种不能catch的异常判断, 断言是一种调试方式,断言失败会抛出AssertionError,只能在开发和测试阶段启用断言;

反射[1]

  1. 反射就是在运行时候对实例一无所知情况下,去获取对象属性的方式。 我们知道所有非基础的数据结构实际上都是class这个类的实例。 例如下面代码就是将string传入进行class, 创建一个cls的string实体。 要知道这个创建是私有的, 因此只有jvm才能创建。

Class cls = new Class(String);

由于每个创建的class都有对应的Class实例, 那么其信息一定保存在Class实体中,这种通过Class实例获取class信息的方法称为反射(Reflection)。 获取之后还能进行修改。
3. 实际用途: (1)正常来说我们使用类都是知道了之后再去调用的, 但是对于一些组件代码有很大的用处, 这些工具和组件需要这个工具。 例如一般我们链接数据库都会把属性写死到代码中,创建一个链接类。 但是如果配置参数变动需要修改代码或者即使弄个配置文件也要把代码停掉,再运行创建。 但是反射是直接从配置文件中读取配置后再创建对象。 (2) 直接使用class去操作对象, 省去很多细节, 我不用去写这个具体类. 属性, 我只需要写class.属性。 (3) 像一些IDE的自动提示就是这样实现的, 写一个类,一些方法和变量就自动输出出来了。

注释(Annotation)

  1. 注解的理解: 注解就是对这个类、方法、字段、参数加一个标识, 是给编译器做解释。 注解可以分为3类,第一类就是语言自带的注解, 编译之后就会被删掉。 第二类是有些工具给 的注解, 会被编译进行但是不会加载到内存。 第三类是内存中都包含的注解, 一般是自己实现的。
  2. 定义注解:一般就是定义一个注解, 然后添加参数和默认值, 然后使用元注解对注解进行修饰。 注解能够用过Class去获取的。因此,读取注解,需要使用反射API。
  3. 如何使用注解: 一般注解定义好之后, 我们即使用了, 但是还是需要自己去写函数, 去通过反射读取注解的属性,来做处理的。注意注解用途逻辑完全是我们自己编写的,JVM不会因为有注解添加任何额外的功能逻辑。
@Target(ElementType.METHOD)
public @interface Report {
    int type() default 0;
    String level() default "info";
    String value() default "";
}

泛型、函数式编程

  1. 泛型就不说了, 其实就是模板编程, 同一套业务, 不同的数据进行就需要这样。很多反射就是泛型实现的。
  2. 而函数型编程进来的参数会包含函数, 就会更加的抽象, 一般是lamaba. 注意lamaba本身就是一个匿名的函数对象, 当你按照他的方式去写的话就是传入了一个对象进去, 会调用其对象的方法。

集合

  1. 集合的意思就是若干个元素的集合, 这里面数量有确定的, 还有不确定的。主要是想通过一个java对象持有若干的其他java对象。 数组就是这样的一个集合, 但是他是长度固定的。
  2. 主要的元素中 list等等这些, 其实都是和c++ 差不多的, 此外需要注意还有一个Collections类提供了一组工具方法来方便使用集合类, 类似C++中的算法部分, 用来处理这些数据。

IO

多线程

  1. java本身jvm就是一个多线程的虚拟机, 有些自定义负责回收内存的线程, 因此对多线程来说是非常支持的, 但是多线程一定要注意同步问题。 后续读写网络、数据库、Web开发等都依赖Java多线程模型。
  2. 线程的顺序无法确定。

网络编程

单元测试、日志等第三方库的使用

  1. 日志 : 这里一般就是先去下载别人开源项目的jar包, 然后写完代码自己使用java 命令行去编译,一般日志会做成静态的单例模式。 此外我们commons的日志还能升级, 例如加载log4j日志, 这个是基于commons日志的升级项目, 我们需要将jar包也加入到classpath中, 然后通过xml配置日志的属性, 这样原来的代码启动common日志后会直接通过xml去配置自己, 然后通过多态将自己的具体实现转接到新的日志库上。
  2. 单元测试: 单元测试就是对现在的代码功能进行测试, 看看是否满足输入和输出。 一般手动的花就是自己写一个main函数去输入一些测试样例, 但是这样太麻烦了。 一般是使用测试框架, 重新写一个测试类,在这个测试类中对想要测试的代码进行断言或者判断, 注意不要增加代码, 就看看输入输出对不对,一些数据或者异常是否是正常的。
@ParameterizedTest
@ValueSource(ints = { 0, 1, 5, 100 })
void testAbs(int x) {
    assertEquals(x, Math.abs(x));
}

refrence

  1. java的反射到底是有什么用处?怎么用? - Java3y的回答 - 知乎
    https://www.zhihu.com/question/377483107/answer/1079967402
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值