<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Java &#8211; 张三太爷</title>
	<atom:link href="https://www.somedoc.net/tag/java/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.somedoc.net</link>
	<description>看前面，黑洞洞</description>
	<lastBuildDate>Sat, 04 Jun 2022 04:23:17 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.1</generator>

<image>
	<url>https://www.somedoc.net/wp-content/uploads/2016/12/cropped-dandycheung-1-32x32.jpg</url>
	<title>Java &#8211; 张三太爷</title>
	<link>https://www.somedoc.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Java 和 Kotlin 中 interface 的不同导致混合编程时出现的一个问题</title>
		<link>https://www.somedoc.net/2022/06/04/java-%e5%92%8c-kotlin-%e4%b8%ad-interface-%e7%9a%84%e4%b8%8d%e5%90%8c%e5%af%bc%e8%87%b4%e6%b7%b7%e5%90%88%e7%bc%96%e7%a8%8b%e6%97%b6%e5%87%ba%e7%8e%b0%e7%9a%84%e4%b8%80%e4%b8%aa%e9%97%ae%e9%a2%98/</link>
					<comments>https://www.somedoc.net/2022/06/04/java-%e5%92%8c-kotlin-%e4%b8%ad-interface-%e7%9a%84%e4%b8%8d%e5%90%8c%e5%af%bc%e8%87%b4%e6%b7%b7%e5%90%88%e7%bc%96%e7%a8%8b%e6%97%b6%e5%87%ba%e7%8e%b0%e7%9a%84%e4%b8%80%e4%b8%aa%e9%97%ae%e9%a2%98/#respond</comments>
		
		<dc:creator><![CDATA[张三太爷]]></dc:creator>
		<pubDate>Sat, 04 Jun 2022 04:23:17 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Kotlin]]></category>
		<guid isPermaLink="false">https://www.somedoc.net/?p=5030</guid>

					<description><![CDATA[让小兄弟做一些新的技术研究，他兴奋地用上了垂涎已久的 Kot <a href="https://www.somedoc.net/2022/06/04/java-%e5%92%8c-kotlin-%e4%b8%ad-interface-%e7%9a%84%e4%b8%8d%e5%90%8c%e5%af%bc%e8%87%b4%e6%b7%b7%e5%90%88%e7%bc%96%e7%a8%8b%e6%97%b6%e5%87%ba%e7%8e%b0%e7%9a%84%e4%b8%80%e4%b8%aa%e9%97%ae%e9%a2%98/" class="more-link">[&#8230;]</a>]]></description>
										<content:encoded><![CDATA[<p>让小兄弟做一些新的技术研究，他兴奋地用上了垂涎已久的 Kotlin 语言，并大加赞赏。其中有个场景是，让他设计一套图像特效的接口与实现。</p>
<p>他用 Kotlin 欢快地写成了这样：</p><pre class="crayon-plain-tag">interface Effect {
    fun apply(input: Bitmap) : Bitmap
}</pre><p>并以之为基础接口，至少实现了三个特效。</p>
<p>我在 review 的时候哭笑不得，因为仍然把我提醒过的选项参数给丢掉了，今天我想修复一下。最简单的办法我是知道的，直接向上述 <code>apply</code> 方法中增加一个参数，然后再把那三个实现相应调整过来，再把相关调用也调整过来即可。</p>
<p>但这不符合我作为一个“勤奋的懒人”的直觉。我的第一目标通常是，尽可能少地修改供给侧，尽量不修改消费侧。是否可以新增一个接口方法，原型上加入选项参数，然后将当前这一接口方法改为对新方法的将选型参数置为空的调用呢？经过摸索，以下代码出炉：</p><pre class="crayon-plain-tag">interface Effect {
    class Options {
        companion object {
            val default: Options = Options()
        }
    }

    fun apply(input: Bitmap) : Bitmap {
        return apply(input, Options.default)
    }

    fun apply(input: Bitmap, options: Options) : Bitmap
}</pre><p>然后再去各个具体实现类中把函数签名中加入 <code>options: Effect.Options</code> 这一新的参数即可。点击编译，顺利通过。作为一个 Kotlin 菜鸟，真是要乐出花来。</p>
<p>然而收获胡萝卜结束不久，大棒随之而来。由于我是“一个 Kotlin 菜鸟”，所以在我想新写一个具体特效时，我决定还是使用 Java（主要原因是现成代码会多一些）。我开开心心地写下如下代码后，惊讶地发现，IDE 提示该类对于派生而来的接口的实现不够完整：</p><pre class="crayon-plain-tag">public class ShadowEffect implements Effect {
    public Bitmap apply(Bitmap input, Effect.Options options) {
        return null;
    }
}</pre><p>Java 需要同时实现两个接口函数，成为这样：</p><pre class="crayon-plain-tag">public class ShadowEffect implements Effect {
    public Bitmap apply(Bitmap input) {
        return apply(input, null);
    }

    public Bitmap apply(Bitmap input, Effect.Options options) {
        return null;
    }
}</pre><p>很显然，在 Kotlin 中，<code>interface</code> 同时接纳了 Java 的 <code>abstract</code> 类的部分特性，允许带有具有实现代码的接口函数存在；而 Java 对派生而来的 Kotlin 接口，只接纳其接口函数声明部分，对其具有的实现予以了摒弃。也就是说，将来的其它实现了 <code>Effect</code> 接口的 Java 类，也都要提供自己版本的 <code>Bitmap apply(Bitmap input)</code> 实现，不能从 Kotlin 的现成 <code>fun apply(input: Bitmap) : Bitmap</code> 实现中受益。</p>
<p>如果为了这样一个共同实现的函数的复用，一个可选的（但是笨拙的）方法是，提供一个新的 Java 基类，如下：</p><pre class="crayon-plain-tag">public abstract class JavaEffect implements Effect {
    public Bitmap apply(Bitmap input) {
        return apply(input, null);
    }
}</pre><p>然后将具体实现类的基类调整为它，并把 <code>implements</code> 转换为 <code>extends</code>。当然，在某种程度上这是令人沮丧的，毕竟抽象类跟接口不是一回事。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.somedoc.net/2022/06/04/java-%e5%92%8c-kotlin-%e4%b8%ad-interface-%e7%9a%84%e4%b8%8d%e5%90%8c%e5%af%bc%e8%87%b4%e6%b7%b7%e5%90%88%e7%bc%96%e7%a8%8b%e6%97%b6%e5%87%ba%e7%8e%b0%e7%9a%84%e4%b8%80%e4%b8%aa%e9%97%ae%e9%a2%98/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Java 服务程序连接 MySQL 出错的解决</title>
		<link>https://www.somedoc.net/2020/12/03/java-%e6%9c%8d%e5%8a%a1%e7%a8%8b%e5%ba%8f%e8%bf%9e%e6%8e%a5-mysql-%e5%87%ba%e9%94%99%e7%9a%84%e8%a7%a3%e5%86%b3/</link>
					<comments>https://www.somedoc.net/2020/12/03/java-%e6%9c%8d%e5%8a%a1%e7%a8%8b%e5%ba%8f%e8%bf%9e%e6%8e%a5-mysql-%e5%87%ba%e9%94%99%e7%9a%84%e8%a7%a3%e5%86%b3/#respond</comments>
		
		<dc:creator><![CDATA[张三太爷]]></dc:creator>
		<pubDate>Thu, 03 Dec 2020 03:45:11 +0000</pubDate>
				<category><![CDATA[备忘录]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[问题解决]]></category>
		<category><![CDATA[Java]]></category>
		<guid isPermaLink="false">https://www.somedoc.net/?p=4672</guid>

					<description><![CDATA[在本地编译一个 Java 服务程序，代码编译通过后，要把数据 <a href="https://www.somedoc.net/2020/12/03/java-%e6%9c%8d%e5%8a%a1%e7%a8%8b%e5%ba%8f%e8%bf%9e%e6%8e%a5-mysql-%e5%87%ba%e9%94%99%e7%9a%84%e8%a7%a3%e5%86%b3/" class="more-link">[&#8230;]</a>]]></description>
										<content:encoded><![CDATA[<p>在本地编译一个 Java 服务程序，代码编译通过后，要把数据库连接改到本地新装的 MySQL 上，连接串形如 <code>spring.datasource.url = jdbc:mysql://127.0.0.1:3306/dev?useUnicode=true&characterEncoding=utf-8</code>，但服务程序启动就会报错 <code>The server time zone value ‘?й???’ is unrecognized or represents more than one time zone</code>。改成 <code>spring.datasource.url = jdbc:mysql://127.0.0.1:3306/dev?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8</code> 后，也即加入了 <code>serverTimezone=UTC&</code> 这一段，问题不再出现。</p>
<p>看起来是时区相关的问题导致的，但是很好奇同在一台设备上，一个系统里，怎么会出现时区问题。留待后续再探。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.somedoc.net/2020/12/03/java-%e6%9c%8d%e5%8a%a1%e7%a8%8b%e5%ba%8f%e8%bf%9e%e6%8e%a5-mysql-%e5%87%ba%e9%94%99%e7%9a%84%e8%a7%a3%e5%86%b3/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>vscode 中开发 Java 服务程序的 JDK 依赖问题的解决</title>
		<link>https://www.somedoc.net/2020/10/21/vscode-%e4%b8%ad%e5%bc%80%e5%8f%91-java-%e6%9c%8d%e5%8a%a1%e7%a8%8b%e5%ba%8f%e7%9a%84-jdk-%e4%be%9d%e8%b5%96%e9%97%ae%e9%a2%98%e7%9a%84%e8%a7%a3%e5%86%b3/</link>
					<comments>https://www.somedoc.net/2020/10/21/vscode-%e4%b8%ad%e5%bc%80%e5%8f%91-java-%e6%9c%8d%e5%8a%a1%e7%a8%8b%e5%ba%8f%e7%9a%84-jdk-%e4%be%9d%e8%b5%96%e9%97%ae%e9%a2%98%e7%9a%84%e8%a7%a3%e5%86%b3/#respond</comments>
		
		<dc:creator><![CDATA[张三太爷]]></dc:creator>
		<pubDate>Wed, 21 Oct 2020 07:26:42 +0000</pubDate>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[问题解决]]></category>
		<category><![CDATA[Java]]></category>
		<guid isPermaLink="false">https://www.somedoc.net/?p=4644</guid>

					<description><![CDATA[前几天写完一个 Java 服务，也写了一个程序执行中的错误问 <a href="https://www.somedoc.net/2020/10/21/vscode-%e4%b8%ad%e5%bc%80%e5%8f%91-java-%e6%9c%8d%e5%8a%a1%e7%a8%8b%e5%ba%8f%e7%9a%84-jdk-%e4%be%9d%e8%b5%96%e9%97%ae%e9%a2%98%e7%9a%84%e8%a7%a3%e5%86%b3/" class="more-link">[&#8230;]</a>]]></description>
										<content:encoded><![CDATA[<p>前几天写完一个 Java 服务，也写了一个程序执行中的错误问题的排查小结。但是当初把 vscode 配置到可以正常运行并调试服务的状态并不是一帆风顺的。最大的问题是 JDK 的依赖问题。</p>
<p>机器上之前调试过一个开源的 Java 网盘应用，安装了 JDK 8。但是这次写的程序一跑，就会报最低需要 Java 11 的 JDK。</p>
<p>下载了 JDK 11，解压，往 vscode 的 settings.json 中增加了以下设置：</p><pre class="crayon-plain-tag">"java.configuration.runtimes": [
        {
            "name": "JavaSE-11",
            "path": "C:\\Dandy\\DevTools\\jdk-11.0.8",
            "default": true
        }
    ],</pre><p>企图达到报错时的提示文字中提到的 JDK 11 只是 vscode 中 Java debugger 插件的要求，运行时仍可使用老的 Java 版本环境的效果，但怎么也做不到这种两全其美的平衡。最后还是把 <code>JAVA_HOME</code> 环境变量一并改掉才可以。</p>
<p>事后在 https://github.com/redhat-developer/vscode-java/wiki/JDK-Requirements#java.configuration.runtimes 处也能找到如下字样：</p>
<blockquote><p>Simply defining JavaSE-11 in java.configuration.runtimes is not enough for vscode-java to start, java.home (or any of its alternative environment variables) still needs to point to a valid JDK 11 location.</p></blockquote>
<p>看上去似乎又是说，不用动系统层面的 <code>JAVA_HOME</code>，而是直接指定 vscode 的 <code>java.home</code> 也可以。没有测试。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.somedoc.net/2020/10/21/vscode-%e4%b8%ad%e5%bc%80%e5%8f%91-java-%e6%9c%8d%e5%8a%a1%e7%a8%8b%e5%ba%8f%e7%9a%84-jdk-%e4%be%9d%e8%b5%96%e9%97%ae%e9%a2%98%e7%9a%84%e8%a7%a3%e5%86%b3/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Java 服务启动后静默退出的可能问题的解决</title>
		<link>https://www.somedoc.net/2020/10/12/java-%e6%9c%8d%e5%8a%a1%e5%90%af%e5%8a%a8%e5%90%8e%e9%9d%99%e9%bb%98%e9%80%80%e5%87%ba%e7%9a%84%e5%8f%af%e8%83%bd%e9%97%ae%e9%a2%98%e7%9a%84%e8%a7%a3%e5%86%b3/</link>
					<comments>https://www.somedoc.net/2020/10/12/java-%e6%9c%8d%e5%8a%a1%e5%90%af%e5%8a%a8%e5%90%8e%e9%9d%99%e9%bb%98%e9%80%80%e5%87%ba%e7%9a%84%e5%8f%af%e8%83%bd%e9%97%ae%e9%a2%98%e7%9a%84%e8%a7%a3%e5%86%b3/#respond</comments>
		
		<dc:creator><![CDATA[张三太爷]]></dc:creator>
		<pubDate>Mon, 12 Oct 2020 10:40:51 +0000</pubDate>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[问题解决]]></category>
		<category><![CDATA[Java]]></category>
		<guid isPermaLink="false">https://www.somedoc.net/?p=4632</guid>

					<description><![CDATA[和团队盘点一个项目。起先是由实习生发起的，用 Spring  <a href="https://www.somedoc.net/2020/10/12/java-%e6%9c%8d%e5%8a%a1%e5%90%af%e5%8a%a8%e5%90%8e%e9%9d%99%e9%bb%98%e9%80%80%e5%87%ba%e7%9a%84%e5%8f%af%e8%83%bd%e9%97%ae%e9%a2%98%e7%9a%84%e8%a7%a3%e5%86%b3/" class="more-link">[&#8230;]</a>]]></description>
										<content:encoded><![CDATA[<p>和团队盘点一个项目。起先是由实习生发起的，用 Spring Boot 打底。发展着发展着，需要将功能拆开，然后就砸到了老夫手上。</p>
<p>项目组织是一个 pom.xml 的文件，一是对 Java 世界的东西不太熟悉，二是对各种开发环境/构建系统也了解不全，已经不清楚 pom.xml 是谁的工程文件了（查了一下，貌似是 Maven 的）。好在 Visual Studio Code 现在够用，能导入。</p>
<p>项目依赖的下载，嗯，在公司的小破网上跑了将近一整天。在此期间，不编译，死写代码。后来到了一个需要阶段性验证的地步，只好先提交到仓库，让其他同学 pull 后编译执行。第一阶段实现一个接口，很顺利，老夫写的代码仅改了一处需要 import 和一个构造函数前少了 public 的问题。</p>
<p>在 Lombok 的加持下（vscode 里也有插件的），跟数据库的交互也很顺畅，简直以为前方就是一马平川了。结果还是 too young too simple 了，而且 this time 就“拿衣物”了。在某个接口的代码完毕之后，程序出现了执行起来很快就退出的情况。没有任何可供探查的信息输出。就是干巴巴的一个通知：</p>
<blockquote><p>HikariPool-1 &#8211; Shutdown initiated&#8230;<br />
HikariPool-1 &#8211; Shutdown completed.<br />
Stopping service [Tomcat]</p></blockquote>
<p>怀疑机器内存不够、本机 Java 环境或者其他支撑环境受损、网络不通畅、数据库表处理失当，等等等，无果。最后，老老实实、仔仔细细、逐行代码进行排查，最终发现一个 dao 接口类的方法是元凶。具体到细节，则是 find 动词检索的字段名，其实在该表中是不存在的。在网上能够搜索到的一个事例（https://blog.csdn.net/a704397849/article/details/90648899）表明，注解（或者我进一步理解为代码生成技术）在编程中带来便利的同时，也把隐患埋藏得更深。</p>
<p>整体排查的时间开销，大概是 6 人时。直接导致老夫于凌晨在东直门大街上瑟瑟发抖地等待出租车的到来，上车后哆嗦了至少五分钟，连话都说不完整，也算是一个奇妙的体验。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.somedoc.net/2020/10/12/java-%e6%9c%8d%e5%8a%a1%e5%90%af%e5%8a%a8%e5%90%8e%e9%9d%99%e9%bb%98%e9%80%80%e5%87%ba%e7%9a%84%e5%8f%af%e8%83%bd%e9%97%ae%e9%a2%98%e7%9a%84%e8%a7%a3%e5%86%b3/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
