为了账号安全,请及时绑定邮箱和手机立即绑定
Java 枚举类

本小节我们将一起学习 Java 枚举类,将涉及到什么是枚举类、为什么需要枚举类,如何自定义枚举类以及如何使用枚举类,Enum 类的常用方法等内容。理解为什么需要枚举类以及学会自定义枚举类是本小节学习的重点。

Java 输入输出流

本小节将会介绍基本输入输出的 Java 标准类,通过本小节的学习,你将了解到什么是输入和输入,什么是流;输入输出流的应用场景,File类的使用,什么是文件,Java 提供的输入输出流相关 API 等内容。

Java 封装

上一小节中,我们已经对类和对象有了一个基本的认识。不止于 Java,在各个面向对象语言的书籍资料中,都会提到面向对象的三大特征:封装、继承、多态。本小节我们就从封装开始,探讨面向对象的特征。本小节我们将学习什么是封装、为什么需要封装,最后也会以一个 NBA 球员类的案例来实现封装。

Java 继承

本小节我们将学习 Java 的继承,通过本小节的学习,你将知道什么是继承,继承有什么特点,如何实现继承,方法重写的概念和实现,方法重写和方法重载是比较容易混淆的概念,我们也会介绍两个概念的区别,这些都是本小节的重点,本小节的最后我们还会介绍 super 关键字以及 final 关键字。

2.2 Java 代码

项目中包含的 java 源文件:MainActivity.java:// Used to load the 'native-lib' library on application startup.static { System.loadLibrary("native-lib");}@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Example of a call to a native method TextView tv = findViewById(R.id.sample_text); tv.setText(stringFromJNI());}/** * A native method that is implemented by the 'native-lib' native library, * which is packaged with this application. */public native String stringFromJNI();System.loadLibrary:加载我们自己的原生库 native-lib;setText(stringFromJNI()):把 stringFromJNI 函数返回的字串赋给 TextView 显示出来;public native String stringFromJNI():声明本地方法 stringFromJNI。

Java 日期和时间

本小节我们将学习 Java 中的日期和时间,日期和时间在我们的实际开发中非常常用,例如用户的注册、数据的增删改、对敏感信息的操作等等都需要记录下日期和时间。通过本小节的学习,你将了解到什么是日期、什么是时间、什么是时区,Java 中 Date 类的 API 介绍,Calendar 日历类的使用,LocalDateTime 类的相关 API 介绍等内容。

3. Java 非阻塞式 Socket 编程

介绍 Java 非阻塞式 Socket 编程,就得介绍 Java NIO。Java NIO 是 Java New IO API,有时也解释为 Java Non-blocking IO。通过 Java NIO 可以实现 Java 非阻塞 Socket 编程。Java NIO 是 Java 1.4 支持的,它将 Socket 数据流抽象为一个 Channel(管道),Socket 数据读写是通过 Channel实现的,并且提供了 Buffer 机制,提高数据读写的性能。Java NIO 通常用来编写高性能 Java 服务器程序。在 Java 1.7 以后,Java NIO 对磁盘文件处理得到了增强,可以将 Socket I/O 和 文件 I/O 融合在 Java NIO 中。Java NIO 提供的新的类结构如下:类名称功能说明ServerSocketChannel表示服务端 TCP Socket 的监听 Channel。ServerSocketChannel 提供的工厂方法 open,用于创建它的实例;同时它提供了 accept 方法用于在服务器中接收新的客户端连接请求,返回值是 SocketChannel 类的实例。SocketChannelSocketChannel 表示一个 TCP 通信 Channel,可以通过它的 open 方法创建,也可以通过 ServerSocketChannel 的 accept 方法创建。SelectorJava I/O 事件多路复用机制,用于同时监听多个 Channel 的读、写、监听事件SelectionKey用于表示具体的事件对象ByteBuffer通过 SocketChannel 进行数据读写,依赖 ByteBufferServerSocketChannel 和 SocketChannel 同时支持阻塞式和非阻塞式,默认是阻塞式。可以通过如下的方法,打开非阻塞式。// 配置监听 ServerSocketChannel 为非阻塞模式ServerSocketChannel serverChannel = ServerSocketChannel.open();serverChannel.configureBlocking(false);// 配置服务器新建立的 SocketChannel 为非阻塞模式SocketChannel newSock = serverChannel.accept();newSock.configureBlocking(false);SocketAddress serverAddr = new InetSocketAddress("127.0.0.1", PORT);SocketChannel sock = SocketChannel.open(serverAddr);// 配置客户端 SocketChannel 为非阻塞sock.configureBlocking(false);

3. 新建 Java 项目的设置

下面是对 New Java Project 窗口内信息的一些说明,如下图所示:其中,我们需要做的事情如下:填写我们的项目名称和选择项目的存放路径此处我们填写 my-first-java-project。项目的存放路径使用默认的即可。如需修改存放路径,可以取消 Use default location 选项,然后在下方的文本框中填写其他路径。选择JRE这里我们使用的 Java 版本是 11。通常来说我们会选择自己配置的 JDK 作为项目的JRE。选择项目布局通常我们会把 Java 源文件和编译后的 class 文件存放到不同的文件夹中。选择工作集这里我们不需要使用到工作集,所以保持默认,不勾选。工作集的主要功能是对多个 Java 项目开发时进行一个管理。Java 项目名的命名规范这里推荐参考 spring 项目,即使用全小写,如多个单词则以短横杠(-)分开,如:完成上面的配置,我们点击 Next 进入下一步:这一步,其实是对 Java 构建的一些设置,比如导入一些额外的库。这个界面的内容基本保持默认即可,如需修改,我们后面也可以重新进入该界面进行修改。这里要注意的是我们可以取消勾选 create module-info.java 选项。点击 Finish 按钮,此时,Eclipse 可能会弹出一个窗口问我们是否需要切换到 Java透视图,我们选择 No,或者选择 Open Perspective 来切换到 Java透视图都可以。我们这里先不进行切换,因为透视图的切换随时可以进行,所以直接点击 No 即可。接着,我们就可以在 Project Explorer 视图中看到 my-first-java-project 项目了。至此,我们的 Java 项目就创建出来了。

Java 类和对象

经过前面一系列的学习,你可能对类和对象已经有了一定的了解,这是因为 Java 语言是纯面向对象的编程语言,类和对象在 Java 中无处不在。在程序设计时,我们针对事物的特征和行为使用代码进行实现,就是面向对象编程。可以毫不夸张地说,面向对象编程是中大型项目代码最好的组织形式。本小节我们将学习类和对象的基本概念、类和对象的关系,除了字段和方法,在类中都可以定义什么其他内容。也会讲解什么是实例化、实例化过程是怎样的,构造方法是什么,如何定义以及其特点,this 关键字的含义和使用。

Java 数组

数组在编程语言中是非常重要的数据结构。本小节我们来一起学习 Java 数组,通过本小节的学习,你将了解到数组的基本概念,如何声明数组以及数组的声明有哪些方式,如何初始化数组以及数组初始化有哪些方式,数组的常用操作有哪些,多维数组的声明、创建、初始化以及迭代等等。多维数组部分将以二维数组进行为例讲解,理解了二维数组,再去理解多维数组就相对容易了。

3. 运行 Java 程序

现在,我们有了一个包含 main 方法的 Java 类了,我们可以在main方法中添加一句打印语句。如果要运行这个 Java 程序,我们可以通过点击工具栏中的绿色运行按钮。如果是第一次运行,我们可以选择点击绿色运行按钮旁边的倒三角选项,在弹出的菜单中选择我们 Run As,接着选择我们要运行的类型,如下图所示:此时,Eclipse 会检查项目中哪些文件没有保存,如果有没有保存的文件,将会弹出窗口询问是否保存,如下图所示:选择 OK 后,我们的程序将会运行,如下图所示:另一种常用的运行程序的方式是通过鼠标右键点击 Java 类中的空白处,在弹出的窗口中选择 Run As,如下图所示:

2. 部署java后台服务

Nginx 部署 Java Web 服务时,主要用到是 Nginx 的代理转发功能,对于不同类型的接口而言,可能会有不同的转发逻辑。如果是使用 spring cloud 这样的微服务框架,每个服务可能会部署多个会这分开部署在不同机器,在 Nginx 同样只需要使用 proxy_pass 指令将 http 请求转发到对应的上游服务上即可,同时负载均衡模块也在 java web 后台服务中用到的比较多。最后是在java web 的开发中,也常常会涉及到 websocket 协议,因此 Nginx 在部署 java web 服务时也会用到 websocket 代理转发。所以 Nginx 在部署 Java Web 服务时的基本配置大概如下:...http{ server { # 监听8080端口 listen 8080; # 指定域名,不指定也可以 server_name www.xxx.com; # 参数调优 client_max_body_size 20m; client_body_buffer_size 128k ... # 如果使用多个后台服务,可以配置负载均衡 ... # 访前端的 vue 页面 location / { ... } # vue 页面中向后台 java 服务发送请求 location /xxxx { proxy_pass http://xxxx:xx/xxx; } # 配置多种方向代理,不同类型接口有不同的转发方式 ... # 如果有,则配置websocket代理 location /xxxy { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://xxxxx:xx/yyy; } } }...如果涉及的服务较多, Nginx 的配置往往会拆成多个文件进行编写,这样就用到了前面提到的 include 指令。

Java 条件语句

条件语句通过判断给定条件的真假来控制程序的执行。在上一小节中,我们已经简要介绍过了语句和块的概念。那么本小节我们将进一步展开介绍 Java 中所有类型的条件语句。

Java 内部类

本节我们将介绍 Java 中的内部类。通过本节的学习,我们将了解到什么是内部类,内部类的分类和作用。在内部类的分类部分,我们将逐一学习各个类型的内部类如何定义,如何实例化以及各自的特点,要注意区分不同类型内部类的异同。有了这些基础知识之后,我们也会结合示例介绍为什么需要内部类。

第一个 Java 程序

本节我们将以Windows操作系统为例,编写并执行第一个Java程序。在这之前,请确保你的操作系统上已经安装了JDK

5. Java ByteBuffer 的字节序

那么 JVM 作为一部独立运行的机器,它的字节序又是如何呢?通过 Java 程序测试字节序的思路和 C 程序的一致,代码片段如下: public static void checkEndian() { int x = 0xAABBCCDD; ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES); buffer.putInt(x); byte[] lbytes = buffer.array(); for (byte b : lbytes){ System.out.printf("%X\n", b); } }关于 JAVA 程序需要说明的是 JAVA 中没有指针的概念,所以不能通过取地址的方式直接打印内存的值。需要借助 JAVA 的 ByteBuffer,将 int 型数值存储到 ByteBuffer 中,然后将 ByteBuffer 转换成字节数组,通过打印数组的方式来达到我们的目的。引用 ByteBuffer 需要通过语句 import java.nio.ByteBuffer; 导入ByteBuffer 类。JAVA 测试结果:AABBCCDD从输出结果可以看出 ByteBuffer 默认是以大端序来存储整数的,因为 Java 虚拟机本身采用的就是大端序,ByteBuffer 也要和整个系统保持一致。当然,ByteBuffer 也提供了 ByteBuffer order() 和 ByteBuffer order(ByteOrder bo) 方法,用来获取和设置 ByteBuffer 的字节序。另外,像一些多字节 Buffer,如 IntBuffer、LongBuffer,它们的字节序规则如下:如果多字节 Buffer 是通过数组(Array)创建的,那么它的字节序和底层系统的字节序一致。如果多字节 Buffer 是通过 ByteBuffer 创建的,那么它的字节序和 ByteBuffer 的字节序一致。测试程序如下: public static void checkByteBuffer(){ ByteBuffer byteBuffer = ByteBuffer.allocate(Long.BYTES); long [] longNumber = new long[]{ 0xAA,0xBB,0xCC,0xDD }; LongBuffer lbAsArray = LongBuffer.wrap(longNumber); System.out.println("The byte order for LongBuffer wrap array: " + lbAsArray.order()); LongBuffer lbAsByteBuffer = byteBuffer.asLongBuffer(); System.out.println("The byte order for LongBuffer from ByteBuffer: " + lbAsByteBuffer.order()); }执行结果:The byte order for LongBuffer wrap array: LITTLE_ENDIANThe byte order for LongBuffer from ByteBuffer: BIG_ENDIAN如果在上面的 checkByteBuffer 方法中,首先将对象 byteBuffer 的字节序设置为 ByteOrder.LITTLE_ENDIAN(通过 ByteBuffer 的 order 方法设置),然后再创建 lbAsByteBuffer 对象,那么 lbAsByteBuffer 的字节序该是什么呢?

2.2 Java NIO 中其他 Channel 接口

在 Java NIO Channel 体系中,对于 Socket 的抽象、数据读、数据写、数组形式的多缓冲读、数组形式的多缓冲写等功能分别进行了抽象,每一个功能都对应一个 Java 接口,下来我们分别做一个说明。java.nio.channels.ReadableByteChannel 是一个 Java Interface,是对 Channel 读操作的抽象,声明的接口如下:public int read(ByteBuffer dst) throws IOException;Channel 的 read 方法是从 I/O 设备读取数据,保存在 ByteBuffer 中,为此调用者必须提供 ByteBuffer 用以保存数据。返回值是读取的字节数、0、或者 -1。如果是阻塞式 Channel,read 至少返回 1 或者 -1;如果是非阻塞式 Chanel,read 可能会返回 0。java.nio.channels.WritableByteChannel 是一个 Java Interface,是对 Channel 写操作的抽象,声明的接口如下:public int write(ByteBuffer src) throws IOException;Channel 的 write 方法是从 ByteBuffer 读取数据,写入 I/O 设备中,为此调用者必须将要写出去的数据保存到 ByteBuffer 中。返回值是写入的字节数、0、或者 -1。如果是阻塞式 Channel,write 返回请求写入的字节数 或者 -1;如果是非阻塞式 write 可能会返回 0。java.nio.channels.GatheringByteChannel 是一个 Java Interface,是对 Channel 写操作的抽象,可以写入一个数组,支持对多个 ByteBuffer 的写入,声明的接口如下:public long write(ByteBuffer[] srcs, int offset, int length) throws IOException;public long write(ByteBuffer[] srcs) throws IOException;java.nio.channels.ScatteringByteChannel 是一个 Java Interface,是对 Channel 读操作的抽象,可以读入一个数组,支持对多个 ByteBuffer 的读入,声明的接口如下:public long read(ByteBuffer[] dsts, int offset, int length) throws IOException;public long read(ByteBuffer[] dsts) throws IOException; java.nio.channels.NetworkChannel 是一个 Java Interface,表示一个 Socket。实现此接口的 Channel 表示对 Socket 的封装。java.nio.channels.SelectableChannel 是一个 Java Interface,用于和 java.nio.channels.Selector 集成。声明的主要接口如下:public abstract SelectableChannel configureBlocking(boolean block) throws IOException;public final SelectionKey register(Selector sel, int ops) throws ClosedChannelException实现了 SelectableChannel 接口的类,可以将 I/O 操作设置为非阻塞模式,同时可以注册到 Selector,通过 I/O 多路复用机制监听事件。java.nio.channels.ByteChannel 也是一个 Java 接口,只是实现了 java.nio.channels.ReadableByteChannel 和 java.nio.channels.WritableByteChannel 两个接口。ByteChannel 本身没有声明任何接口,实现了读写聚合的功能。

4.5 兼容Java的<strong>平台类型</strong>

通过上述我们可以知道在 Kotlin 中拥有着与 Java 中完全不一样的类型系统。在 Java 中是不存在所谓的可空类型和非空类型。但是我们都知道 Kotlin 与 Java 的互操性很强,几乎是完全兼容 Java。那么Kotlin是如何兼容Java中的变量类型的呢?我们在 Kotlin 中肯定需要经常调用 Java 代码,有的人可能会回答说 Java 中使用@NotNull和@Nullable注解来标识。确实 Kotlin 可以识别多种不同风格的注解,包括 javax.annotation、android.support.annotation、org.jetbrains.annotation等。但是一些之前的第三方库并没有写的这么规范,显然无法通过这种方式完全解决这个问题。所以 Kotlin 引入一种新的概念叫做: 平台类型,平台类型本质上就是Kotlin不知道可空性信息的类型,既可以把它当做可空类型又可以把它当做非空类型。 这就意味要像 Java 代码中一样对在这个类型上做的操作负全部责任。所以对于 Java 中函数参数,Kotlin 去调用的时候系统默认会处理可空类型(为了安全性考虑),如果明确了不为空,可以直接把它修改为非空类型,系统也是不为报编译错误的,但是一旦这样处理了,必须保证不能为空。那么问题来了,很多人就疑问出于安全性考虑为什么不直接全部转化可空类型呢? 实际上这种方案看似可行,实际上有点不妥,对于一些明确不可能为空的变量还需要做大量额外的判空操作就显得冗余。否则非空类型就没有存在的意义了。

2. Java 多线程编程方法

由于本节会涉及到 Java 多线程编程,所以需要你能预先掌握 Java 多线程编程的方法。比如,线程的创建,线程的启动,线程之间的同步和线程之间的通信。在 Java 平台下,创建线程的方法有两种:第一,是创建一个用户自定义的线程类,然后继承 java.leng.Thread 类,同时要覆写它的 run 方法,调用它的 start 方法启动线程。例如:class MyThread extends Thread{ @Override public void run() { super.run(); }}new MyThread().start();第二,是创建一个任务类。首先,实现 Runnable 接口,并且重写它的 run 方法。然后,创建 java.leng.Thread 类的对象,同时将 Runnable 的实例通过 java.lang.Thread 的构造方法传入。最后,调用 java.lang.Thread 的 start 方法启动线程。例如:class MyTask implements Runnable{ @Override public void run() { }}new Thread(new MyTask()).start();

6.2 Java 实现饿汉式单例

public class Singleton implements Serializable { private Singleton() {//构造器私有化 } private static final Singleton mInstance = new Singleton(); public static Singleton getInstance() {//提供公有获取单例对象的函数 return mInstance; } //防止单例对象在反序列化时重新生成对象 private Object readResolve() throws ObjectStreamException { return mInstance; }}对比一下 Kotlin 和 Java 的饿汉式的单例实现发现,是不是觉得 Kotlin 会比 Java 简单得多得多。

Java 序列化与反序列化

上一小节我们学习了 Java 的输入输出流,有了这些前置知识点,我们就可以学习 Java 的序列化了。本小节将介绍什么是序列化、什么是反序列化、序列化有什么作用,如何实现序列化与反序列化,Serializable 接口介绍,常用序列化工具介绍等内容。了解序列化的用途、学会如何进行序列化和反序列化操作是本小节的重点内容。

使用 Nginx 部署 Java web 服务

比较早之前,部署 Java web 服务只是单纯使用 Tomcat 做 Web 服务器,前后端代码融合在一个工程之中。Tomcat 启动后对外提供一个端口接收和相应 http请求。随着 Nginx 的越来越流行,同时加上其优秀的反响代理和负载均衡功能,我们在线上的 Java web 通常会结合二者,即使用 Nginx + Tomcat 的方式来部署 Java web 服务。最近两年,随着微服务化和前后端工程分离思想的流行,使用 Spring Boot 和 Vue 框架进行 Java web 开发的人的人越来越多。由于前后端分离后需要解决请求跨域的问题,往往会使用 Nginx 做一层反向代理,这样可以减少一些代码风险。所以,目前主流的 Java web开发模式是:基于 Vue 等优秀的前端框架完成页面开发;使用 Spring Boot 等 java web 框完成后端服务开发;前端工程打包后是一堆静态文件,可以直接由 Nginx 进行代理访问;后端服务启动后会占用端口等待请求,Nginx 将使用反向代理功能将前端发起的 http 请求转到对应的后台服务去处理。如果在多台机器上部署了相同的服务,还可以使用 Nginx 中的负载均衡功能,将请求均匀分发到上游的服务,实现系统的高可用性。

2. 什么是 Java 的内存模型

定义: Java 内存模型(即 Java Memory Model,简称 JMM)本身是一种抽象的概念,并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。

1.2 替代 Java 中的匿名内部类

我们都知道在 Java 中有匿名内部类,一般情况直接通过 new 匿名内部类对象,然后重写内部抽象方法。但是在 Kotlin 使用 object 对象表达式来替代了匿名内部类,一般匿名内部类用在接口回调比较多。比如 Java 实现匿名内部类:public interface OnClickListener { void onClick(View view);}mButton.setOnClickListener(new OnClickListener() {//Java创建匿名内部类对象 @Override public void onClick(View view) { //do logic }});然而在 Kotlin 并不是直接创建一个匿名接口对象,而是借助 object 表达式来声明的。interface OnClickListener { fun onClick()}mButton.setOnClickListener(object: OnClickListener{//Kotlin创建object对象表达式 override fun onClick() { //do logic }})

3.2 Java 文件编写

以上代码主要实现了两个 Button 及一个 ScrollView,可以看到 ScrollView 中只有一个 LinearLayout,而 LinearLayout 中只有两个 Button,所以我们需要在 Java 代码中动态添加 Button,这里也可以让大家熟悉一下如何动态创建并添加 Button。接下来在 Java 代码中主要做两件事:为两个 Button 设置点击事件,分别实现回到顶部及跳转到底部;往 ScrollView 中添加 View,并绑定点击事件。代码如下:package com.emercy.myapplication;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.LinearLayout;import android.widget.ScrollView;import android.widget.Toast;public class MainActivity extends Activity implements View.OnClickListener { public static final int BUTTON_COUNT = 10; private ScrollView mScrollView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.bt_to_top).setOnClickListener(this); findViewById(R.id.bt_to_bottom).setOnClickListener(this); mScrollView = findViewById(R.id.scrollView); LinearLayout layout = findViewById(R.id.button_group); for (int i = 0; i < BUTTON_COUNT; i++) { Button button = new Button(this); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); params.topMargin = 100; layout.addView(button, params); button.setOnClickListener(this); button.setText(i + ""); } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.bt_to_top: mScrollView.fullScroll(ScrollView.FOCUS_UP); break; case R.id.bt_to_bottom: mScrollView.fullScroll(ScrollView.FOCUS_DOWN); break; default: Toast.makeText(this, "当前点击的是第" + ((Button) v).getText() + "个Button", Toast.LENGTH_SHORT).show(); break; } }}效果如下:我们在代码中通过 for 循环往 ScrollView 中添加了 10 个 Button,动态添加一个 View 主要有以下 4 步:通过构造器创建 View。设置其属性(宽、高、margin、padding 等)。设置响应事件(比如点击、触摸、滚动等)。添加到相应的 ViewGroup 中。我们在创建 Button 的同时通过setText及setOnClickListener设置了文本及点击事件,然后在点击的时候展示当前 Button 的序号。

4.JAVA 代码实现

在说明求解钢条切割问题的整个过程之后,接下来,我们看看如何用 java 代码实现钢条切割问题的求解。import java.util.ArrayList;import java.util.List;public class ActivitySelect { public static void main(String args[]){ //活动集合a int a[] = {1,2,3,4,5,6,7,8,9,10,11}; //活动开始时间集合s int s[] ={1,3,0,5,3,5,6,8,8,2,12}; //活动结束集合f int f[] ={4,5,6,7,9,9,10,11,12,14,16}; //活动选择存放集合A List<Integer> A = new ArrayList<>(); int n = s.length; A.add(a[0]); int k =0; //遍历选择活动 for (int i=1; i<n; i++){ if(s[i] >= f[k]){ A.add(a[i]); k = i; } } System.out.println("活动选择问题的选择活动结果为:"); System.out.println(A); }}运行结果如下:活动选择问题的选择活动结果为:[1, 4, 8, 11]代码中第 7 行至第 14 行分别初始化活动和对应的开始时间、结束时间以及活动选择过程中存放选择的活动集合,代码的第 16 至 18 行对应着开始的活动选择初始化工作,因为 java 数组的下标从 0 开始,所以这里面我们第一个选择的活动为 a [0],而不是伪代码中的 a [1]。代码的第 20 行至 26 行 for 循环遍历活动选择,按照贪心选择的方法选择对应的活动,放入最终的结果集 A 中 ,代码的 28 行 29 行输出相关的活动选择结果。

4. 运行 Java 程序(传参)

在 Eclipse 中,运行 Java 程序的时候我们可以选择传递参数或作一些设置,这里我们看看如何给我们的 Java 程序传参数。首先,我们添加一些代码,输出我们传入的参数,如下图所示:现在,让我们选择 Run Configurations… 选项,如下图所示:在弹出的运行设置窗口中,我们选择到我们的 HelloWorld 程序,然后选择 Arguments 选项,填写要传的参数,多个参数间使用空格分隔,如下图所示:接着点击 Run,我们将会看到控制台会把我们的参数输出,如下运行结果,如下图所示:

3.3 使用 Java 连接 MySQL

Java 连接 MySQL 分为五个步骤:// 注册JDBC驱动Class.forName(JDBC_DRIVER);// 打开链接Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);// 执行查询Statement stmt = conn.createStatement();String sql = "SELECT sno, sname FROM student";ResultSet rs = stmt.executeQuery(sql);// 展开结果集数据库while(rs.next()){// 通过字段检索String no = rs.getString("sno");String name = rs.getString("sname");// 输出数据System.out.println("no: " + no + ", name: " + name);// 完成后关闭rs.close();stmt.close();conn.close();

1.2 Java 代码如何与 Tomcat 合作?

Tomcat 也可称作 Servlet 容器,Servlet 是它与 Java 应用的桥梁,Tomcat 重点解决了 Http 的请求连接,使得 Java 应用可以更专注处理业务逻辑。Servlet 是一套规范,所以它主要的工作就是定义一些接口,每一个接口解决不同的逻辑功能。请求到达 Tomcat,Tomcat 的 Servlet 齿轮转动(调用)起来,触发了 Servlet 的应用代码。

6.3 Java 中的集合与 Kotlin 中集合对应关系

我们刚刚说到在 Kotlin 中集合的设计与Java不一样,但是每一个 Kotlin 的接口都是其对应的 Java 集合接口的一个实例,也就是在 Kotlin 中集合与 Kotlin 中的集合存在一定的对应关系。Java 中的 ArrayList类和 HashSet 类实际上 Kotlin 中的 MutableList 和 MutableSet 集合接口的实现类。把这种关系加上,上面的类关系图可以进一步完善。

直播
查看课程详情
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号