JAVA基础学习(一)—— 编程结构与OOP

本文介绍了JAVA编程的基础知识,包括基本编程结构(HelloWorld示例、数据类型、数组与字符串、数值计算与流程控制),类与对象的概念(面向对象、构造器、方法与字段),以及类与对象的关系(继承、依赖、关联)。
摘要由CSDN通过智能技术生成

本系列适合有C++/Python/Golang等编程基础的同学,对JAVA基础知识进行归纳总结。


前言

JAVA作为一门编程语言,分为三个版本。

SE标准版,包含基础语法、多线程、IO流等核心类;

EE企业版,包含SE的基础上还有扩展部分如Spring、mybatis、JDBC等;

ME微型版,包含SE的部分类库,又有自己的扩展,包含移动类、嵌入式开发等等。


一、JAVA基本编程结构

1、Hello World!

        对于一个编程菜鸟而言,学习编程语言的第一站便是hello world。

public class HelloWorld{
    public static void main(String[] args){
        System.out.println("Hello World");
    }
}

        在这段代码中,我们要注意的是:

1)类名必须以英文字母开头,习惯上首字母大写,驼峰命名法;

2)public代表公开访问,没有它,则程序无法在命令行执行;

3)程序入口函数必须是static静态方法,函数名是main,参数类型为String[];

4)文件名必须和公开类的名字一样,并以.java结尾;

5)main函数不需要返回值,因此void类型。

        然后我们要开始运行程序了。使用javac HelloWorld.java编译程序;使用java HelloWorld来运行编译生成的HelloWorld.class程序即可。有关其涉及底层原理会在JVM、内存管理等后续章节中叙述。

2、数据类型

        JAVA中的数据类型有基本类型引用类型两种。下面说的皆是变量,对于常量可以使用final关键字来修饰,如final Double PI=3.1415926;

        基本类型包括整数类型、浮点数类型、字符类型、布尔类型

        整数类型:byte占一个字节,short占两个字节,int占四个字节,long占8个字节。类型转换时只能由数据范围小的转换为数据范围大的。值得注意的是,由于虚拟机的存在,不管在32位还是64位系统上,java的数据类型都是一样的,和C++区分开。

        浮点数类型:Double占8字节,float占4字节。float在表示时需要在后面加上f后缀。特殊的浮点值NaN代表非数字,比如if(Double.isNaN(x))代表判断x是否是一个数字。对于浮点数是否相等,可以使用Math.abs(x-y)<0.00001来判断。

        字符类型:char占两个字节。使用单引号。

        布尔类型:boolean只有true与false两种,理论上1bit即可,但JVM中使用4字节表示。与C++不同,不能用0,1表示false,true。 

        引用类型是除基本类型以外的类型。包括数组、类、接口、枚举、注解,会在之后详解。

        这里说明一下二者的区别:首先,java中数据的存储是在堆中开辟内存,保存对象基本信息,在栈中只保存堆内存地址。基本类型是直接存储在内存栈上,而引用类型是继承自Object类,“引用”存储在栈上、具体值存储在堆上。另外一个区别是,基本类型在传参时,形参修改,实参不变;引用类型直接指向实际值的地址,形参修改,实参改变。

        其他类型如果整型和浮点型不能满足数值范围要求,可以使用Math包中的BigInteger与BigDecimal。BigInteger a=BigInteger.valueOf(100);//将基本类型转化成大数据类型。注意由于java没有运算符重载,因此不能使用+,*,需要用add,multiply来替代。除法取余操作亦是如此,可自行查阅资料。

3、数组与字符串

        数组类型是引用类型,可以使用int[] ans=new int[5];或者int[] ns=new int[]{1,2,3,4,5}来定义。数组中某个元素发生修改时,栈中存储的地址,会重新指向一个新的堆内存,该内存中存放修改后的元素。数组遍历有两种方案,一种是for(int i=0;i<ans.length;i++)一种是for(int n:ans),与C++极为类似。值得注意的是,java中由于内存分配的关系,数组实际上是一维数组,每个元素可以使不同大小的数组,即不规则数组,这与C++不一样。

        数组中常用的函数包括:int x=Arrays.binarySearch(ans,target)表示使用二分查找,找出已排序数组中等于目标值的元素的索引,没有则返回-1;Arrays.fill(ans,val)用val来填满整个数组;Arrays.sort(ans)。这里需要导入Arrays包,import java.util.Arrays;

        补充字符串类型,字符串类型String是引用类型,本身是class,内部是通过char[]数组实现。一般我们直接定义为String s1="Hello",底层是String s1=new String(new char[]{'H','e','l','l','o'});JAVA提供了如前者一样的字面量来实现。

        JAVA的字符串最大特点是不可修改,当修改其中一个char时,相当于重新new一个字符串,重新指向新的堆内存。这里和golang比较相像。

        字符串的拼接可以使用+号,问题是,在一个循环中,每次都会重新创建一个字符串对象,然后使用并抛弃,影响GC效率。可以使用StringBuilder或StringJoiner预分配缓冲区来解决。

//使用StringBuilder
StringBuilder s = new StringBuilder(1000);
for (int i = 0; i < 800; i++) {
    s.append(i);
}
String s = s.toString();

//使用StringJoiner
String[] n = {"A", "B", "C"};
var s = String.join(", ", n);

        一般的拼接使用StringBuilder即可,但对于分隔符的情况使用StringJoiner更合适,由于原本的StringJoiner需要指定头部和尾部,因此可以用join方法来快速拼接。

        字符串常用函数包括(仅列出6种,其余在用到时学习):

String s="Hello!";
//获取子串
String s1=s.substring(0,3);
//判断s是否以s1为后缀
boolean s2=s.endsWith(s1);
//判断s是否以s1为前缀
boolean s3=s.startsWith(s1);
//将s中全部大写变为小写
String s4=s.toLowerCase();
//将s中全部小写变为大写
String s5=s.toUpperCase();
//将s中所有子串l变为目标串s1
String s6=s.replace('l',s1);

4、数值计算与流程控制

        java中运算操作、流程控制与C++中极为类似,在此不一一赘述。需要注意以下几点:

1)==:当我们判断两个对象是否相等时,常使用==。在java中,基本类型可以,但引用类型不行,显然,==仅比较在栈空间的引用类型的“名称”,怎么可能相等呢?要想深度比较,就要使用equals()函数。

String s="Hello";
String t=s;
System.out.println(s.equals(t));//不忽略大小写
System.out.println(s.equalsIgnoreCase(t));//忽略大小写

2)C++中>>不能保证执行的是逻辑运算还是算术运算,java则彻底区分开,使用>>进行算数运算,使用>>>进行逻辑运算。

3)java提供了常用的函数。Math.sqrt(x)计算一个数的平方根;Math.pow(x,a)计算x的a次方;还用Math.PI、Math.E等常量;还有Math.sin、Math.cos等函数。

二、JAVA类与对象

1、面向对象的语言

        与C++一样,java是面向对象的语言。类是实现的核心,类与类之间的关系有多种。

        继承 is-a 是一个特定类与一般类之间的关系,类似于OS中的父子进程;依赖 uses-a 是指偶然、临时性的使用,如一个类中的某个方法使用了另一个类作为参数;关联是两个类之间的强依赖关系,比如一个类成为了另一个类的私有属性,其中一个特例是聚合 has-a ,两个类是有实际关联的,如家庭-孩子、衣服-裤子之类的,另外一种是组合 contains-a ,则是更上一层,头颅-眼睛这种,一个生命周期结束导致另一个也随之结束,这两种只能从语义上进行区分。详细内容可查阅相关书籍,或使用类图自行学习。

2、构造一个类要做什么

        这里会分析构造一个最基础的类需要实现什么。

        一个类的实现无非就三部分:构造器、方法、字段。

1)构造器

        一个构造器的实现必须注意以下几点:

①构造器的名字与类名相同;

②一个类可以有多个构造器、构造器参数可以有多个;

③构造器必须和new一起被使用

        同C++,类的多个构造器也是使用了重载:多个方法具有相同的名字但含有不同的参数,便发生了重载。需要牢记的是,一个类含有多个构造器但没有默认构造器,在调用无参构造是是不合法的。

        在构造器方法或其他方法中,有两类参数:一类是隐式参数用this指代类的对象,一类是显示参数,即方法名后面的参数列表。构造函数内,参数的初始化可以使用this来实现,同C++。另外this有另一个作用,便是在一个构造器的第一句使用this(...)调用另一个构造器,这一点与C++不同。

        除了在构造器中初始化数据外,还有声明赋值来初始化。另外,可以使用初始化块来实现。在java中用{}表示隔离,通过{}初始化块,可以实现,当构造器构造对象后,先初始化,在执行其余部分内容。常用于静态字段初始化,下面便是不使用main函数便可以执行函数:

...
public class Hello{
    static{
        System.out.println("Hello World!");
    }
}
...

        与C++不同,java没有析构函数,可以通过GC来实现垃圾回收。这一点和golang一样,果然业务代码还是需要java/golang这样有大量优化、简易处理、语法糖的编程语言啊。

2)方法与字段 

        编程中对一个实例字段的读写一般通过三个步骤实现:一个私有的数据字段private String name、一个公开的字段访问方法String getName(),一个公开的字段调节器方法void setName。(ps:方法一般小驼峰,类一般大驼峰)。注意,调节器方法一般不要返回可变对象,否则容易破坏封装关系报错。ps:final修饰的字段是不可改变的,如果一个类的所有字段都是final,即为不可改变的。

        静态字段:被static修饰,一个字段只属于这个类,不属于任何对象。一般静态常量比较常见,公开字段很危险,但公开常量字段却没问题,别人只能只读访问,如Math.PI。静态方法:被static修饰,不需要任何对象便可以执行,没有this参数。如Math.pow()。直接使用类名来指代即可。

        方法的参数传递:java只有基本类型与引用类型两种,方法不可能改变值类型的参数,引用类型则可以。比如在tom.changeMoney()函数中,直接传递数据是无法改变tom这个实例的钱的,因此需要通过传递新建的实例对象,加上正确的方法来实现。


总结

        本文主要对java基础知识以及部分类与对象的内容进行归纳总结学习。后续将基础部分更新完,对于SSM、微服务相关将不会细致更新(时间紧迫,秋招后会慢慢更新、学习),而是将我遇到的疑惑以及解决方法更新在博客上,有任何问题欢迎与我评论、私信交流。

  • 25
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值