duangsuse::Echo
719 subscribers
4.28K photos
130 videos
583 files
6.49K links
import this:
美而不丑、明而不暗、短而不凡、长而不乱,扁平不宽,读而后码,行之天下,勿托地上天国。
异常勿吞,难过勿过,叹一真理。效率是很重要,盲目最是低效。
简明是可靠的先验,不是可靠的祭品。
知其变,守其恒,为天下式;穷其变,知不穷,得地上势。知变守恒却穷变知新,我认真理,我不认真。

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
Forwarded from AlPlank (Al Pt)
魔幻的问题。

我先声明一个全局异常变量并赋值null
idea告诉我这里一定是非null(也就是在中间被赋值过)
然后我删掉了赋值……
idea告诉我可能这里没赋值??

#public
Forwarded from AlPlank (Al Pt)
说实话java的 notnull String+null会报出空指针异常真的是缺德啊(所以养成了String==null?"":String的不良习惯
Forwarded from AlPlank (神楽坂 立音)
因为你删掉 null 就是未初始化…
AlPlank
魔幻的问题。 我先声明一个全局异常变量并赋值null idea告诉我这里一定是非null(也就是在中间被赋值过) 然后我删掉了赋值…… idea告诉我可能这里没赋值?? #public
这里给同学一个我觉得有可能的情况: #PL #CS #Java

首先,我得给大家科普一下一些关于控制流的,我之前不知道而现在又知道了的名词:

+ 『短路』操作符(运算符)

这里说的『短路』是指,其连接表达式可能不会被全部求值

比如,C 里的 || (Logical OR) 和 && (Logical AND)

a || b 在 a 为 true 的时候值为 a,b 不需要被求值,否则值是 b 的值

Scheme 里这么定义,当然你也可以列真值表,不过这里不用列:

(define logical-or
(lambda (a b)
(cond
(a
#t)
(else b))))

getA() || getB() || getC()

实际上语义也可能可以这么说:

subroutine {
if (a = getA()) { return a; }
if (b = getB()) { return b; }
if (c = getC()) { return c; }
}

如果 getA() 为『真』,实际上可以说后面的表达式不会被求值
这就称为『getB(), getC()』被“短路”了(参考电子电路基础的短路)
这种操作符被称为短路操作符

a && b ,实际上经常可以认为是

subroutine {
if (a) if (b) { return true; }
return false;
}

实际上呢?上面的程序也等价于下面这个,因为 if(b) 的 else branch (语法上不存在,这里是方便理解)实际上直接 fall through 到了 return false:
if (...) .. else .. 嵌套当然还是 Java 1-11 里的就近原则

subroutine {
if (a) { if (b) return true; else return false; }
else return false;
}

#Haskell 里,因为有惰性求值,所以你可以定义自己的短路操作符,C 里面就不能定义自己的『短路函数』了(因为 C 是 pass-by-value 的,先求值函数参数再传递求值好的结果

+ 『非短路』操作符

这里就是 ^ 这种啦,就是求值不会因为某个子表达式的结果而导致子表达式不会完全求值的

XOR 的语义,其实在机器学习上也是有入门级别的交流的,XOR 要求其两个参数”不相同“

(define xor (lambda (a b)
(cond
(a (not b))
(b (not a))
(else #f))))

或者也可以这么 define (Chez Scheme 里,我现在觉得还不如直接用 Haskell 算...)

(define compose
(lambda (f g)
(lambda (args)
(call-with-values (apply g (list args)) f))))

(define (~and a b) (and a b))
(define nand (compose not ~and))
(define (xor a b) (and (or a b) (nand a b)))

欸好像有点写错了... 自己照着理解吧...

(compose (f g) 就是 (lambda x (f (g x))))

好了那前置知识基本可以了

我们来看看 IDEA 为啥可以这么说:

... 我又想废话异常是什么了... 算了不废话了

首先你们看上面的代码:

mainService:while (true) {
tryUpdate:{
Exception exception = null;
for (int i = 0; i < 2; i++) {/*...*/}
AIPtLog.errors("trying getUpdates:\n" + exception);
}
}

一个事件 while 循环,不过还打上了没有用的 tag 叫 mainService
然后是一个我没见过的语法,怎么又是我没见过的

居然还有这种语法... 我一直以为 Java 不让 goto 的... 好像是不让在循环外 goto ... 打住

labeledStatement ANTLR Java8

当然,Java 的语言标准里也有提到:
Unlike C and C++, the Java programming language has no goto statement; identifier statement labels are used with break or continue statements (§14.15, §14.16) appearing anywhere within the labeled statement.

Java 语言标准表达方式冗长严谨复杂,不适合作为第一次理解的目标来选择...

Java 这么做也是有自己的理由,至少,到处 goto 不利于结构化编程。

然后进入正题...
> 我先声明一个全局异常变量并赋值null

好像不是全局的?(考虑到 JVM 的设计,平台语言的托管全局变量都只能限制到 JVM 视角的『类静态』或者说『方法区』变量吧...)
在 Java 的视角,所谓全局变量大概就是静态类变量了吧?(Kotlin 和 Scala 里都是 object 里的成员)

> 然后我删掉了赋值…… idea告诉我可能这里没赋值??
所有 Object (对对象的引用)的默认值的确是空,但是在 Java 和 JVM 的角度,却不是总是遵循这个规则,就 exception 这个方法(局部表)里的变量来说,虚拟机得为它分配一个空间,但是这个空间虚拟机不会自动把它初始化了,必须得手动赋值,在这里 Java compiler 的工作等于是帮你检查程序会不会被虚拟机接受

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.11.8
For instance, the iload instruction (§iload) loads the contents of a local variable, which must be an int, onto the operand stack.

local variable 在使用之前得先赋值(这样才有一个能认的 Type),有时候 Java 允许你这样:

void foo() {
int a; a = 0;
System.out.println("a is " + a);
}

只是因为 Javac 通过控制流分析知道执行 println 的时候 a 肯定不是 uninitialized 而已

找了这篇文章有点参考价值,虽然非常有限
AlPlank
魔幻的问题。 我先声明一个全局异常变量并赋值null idea告诉我这里一定是非null(也就是在中间被赋值过) 然后我删掉了赋值…… idea告诉我可能这里没赋值?? #public
> 说实话java的 notnull String+null会报出空指针异常真的是缺德啊(所以养成了String==null?"":String的不良习惯

提到这个,就不得不说 string concatenation 的标准了...
另外 null 就是 null,String 肯定是 Object 啦,好像不能认为 null 是一种 Object
不过我不知道为啥这里有个 String#isNullOrEmpty.... emmm 我以为是应该抛 NPE 的(OOP 的方法调用 receiver 是空)
好吧我记错了,这是个静态方法... 🙈

根据 《Java 8 语言规范》的 15.18.1 节,字符串拼接中一个参数是 reference 类型,将会把它作字符串转换的结果和字符串进行拼接操作

https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.18.1

If only one operand expression is of type String, then string conversion (§5.1.11) is performed on the other operand to produce a string at run time.
The result of string concatenation is a reference to a String object that is the concatenation of the two operand strings. The characters of the left-hand operand precede the characters of the right-hand operand in the newly created string.
The String object is newly created (§12.5) unless the expression is a constant expression (§15.28).

按照引用的 5.1.11 节,null 指针会被转换为 ASCII 字符串 "null"

https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.11

If the reference is null, it is converted to the string "null" (four ASCII characters n, u, l, l).

???真的会抛出 NPE?我自己拿 Groovy 试了下发现不会...
我好奇是因为《持续企业级 Java 开发》 上面和你所说的完全不同的说法...

"a" + null //=> "anull"

顺便一提,在 Kotlin 里,不要用 tenary 判空默认值了....(虽然 Kotlin 也没有)
Kotlin 有 elvis 操作符...
null ?: "default" 就可以了...

> idea告诉我这里一定是非null(也就是在中间被赋值过)

少女祝祈中... 祝祈完了

首先中间有一段没有展开的 for,不知道有什么代码... 我比较迷...
我这里是什么情况,如果 for 里面什么都没有,IDEA 说 ex 肯定是 null

我假设你的(IDEA 认为 ex 肯定不是 null)的情况是你 try (...) {....} catch (Exception e) { exception = e; } 了?
当然如果没 Catch 也没有调用 java.lang.Exception 及其子类的构造器,好像不容易拿到一个 Exception...

假设 catch (Exception e) { exception = e; } 之后程序控制流会(不管通过什么方式,break, continue,catch)跑到这一行 errors
显然 exception 不会为空吧?(不能抛出 null 的)
duangsuse::Echo
> 说实话java的 notnull String+null会报出空指针异常真的是缺德啊(所以养成了String==null?"":String的不良习惯 提到这个,就不得不说 string concatenation 的标准了... 另外 null 就是 null,String 肯定是 Object 啦,好像不能认为 null 是一种 Object 不过我不知道为啥这里有个 String#isNullOrEmpty.... emmm 我以为是应该抛 NPE 的(OOP 的方法调用 receiver 是空)…
Java 9 以上会使用 StringConcatFactory 的 makeConcatWithConstants 来进行转换(不过也能拿到相同的结果)
然后 Java 8 会生成以下的字节码
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=1, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: ldc #5 // String a
12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: aconst_null
16: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
19: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
25: return
LineNumberTable:
line 3: 0
line 4: 25


看起来就是把 null 作为 Object 往 StringBuilder 里赛了

jshell> StringBuilder builder = new StringBuilder()
builder ==>

jshell> builder.append("a")
$2 ==> a

jshell> builder.append((Object)null)
$3 ==> anull
duangsuse::Echo
Java 9 以上会使用 StringConcatFactory 的 makeConcatWithConstants 来进行转换(不过也能拿到相同的结果) 然后 Java 8 会生成以下的字节码 public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: stack=3, locals=1…
搞基 Jawa9
这厮怕是要能优化别人

final as = new String[] {"a", "v", "c"};
String fin = "";
for (String a : as) {
fin = fin + a;
}

这种程序了
rt. idea 说 ex 肯定是 null
唉,没用的,只有讨论那些有前途的工程技术才可能有人看,我这种人.... 呃.... 你们懒得看。

什么 C 啊、Haskell 啊、编译器啊、静态分析静态检查啊、关系代数啊,算法啊、操作系统啊、软件工程理论啊.... 如果只是作为『赠品』都是浮云

流行的就是那么一点,一招鲜吃遍天,开始的专业得选流行的做才好。

我以后要是上大学,不管专科本科,就和 drakeet 一样,我要学开发,写应用。
偶尔写点好玩点的库什么的... 虽然应用层真的是水浅... 真的就是无脑的堆积,没意思的复制抄改.... 离了网络不能编程...
我真的不想总是写没有 GUI 没有 pattern 的东西,但是也没时间写那些比较耗时的... emmm....

有前途多好... 🙁
计算机科学... 有什么前途
看上次华为吹的,还不如让几个计算机科学的过来整呢。
This media is not supported in your browser
VIEW IN TELEGRAM
duangsuse::Echo
唉,没用的,只有讨论那些有前途的工程技术才可能有人看,我这种人.... 呃.... 你们懒得看。 什么 C 啊、Haskell 啊、编译器啊、静态分析静态检查啊、关系代数啊,算法啊、操作系统啊、软件工程理论啊.... 如果只是作为『赠品』都是浮云 流行的就是那么一点,一招鲜吃遍天,开始的专业得选流行的做才好。 我以后要是上大学,不管专科本科,就和 drakeet 一样,我要学开发,写应用。 偶尔写点好玩点的库什么的... 虽然应用层真的是水浅... 真的就是无脑的堆积,没意思的复制抄改.... 离了网络不能编程...…
恕我直言,应用层真的是浅薄...

比如说,你只需要知道几个名字就可以写代码...

比如 Android 的 support annotations,

@MainThread @WorkerThread @NonNull @Nullable @RequireApi @RestrictTo

比如那个 LayoutFormatter 的 Gradle 插件,我现在就能默写下来(不包括包名,因为太长了没去记)

首先有一个 Task 对象,我们抽象的是 Task
这个 Task 要知道自己要 Format(就是 File readText/process/writeText)哪些文件,我们有 Gradle 的 ConfigurableFileTree 抽象

@Task
class FormatTask extends Task {
private ConfigurableFileTree xmlFiles;

public FormatTask(ConfigurableFileTree tree) { xmlFiles = tree; }
@Override public void run() {
for (File f : xmlFiles.files()) {
Path fp = sun.nio.Paths.getPath(f.toURI());
String fp_contents = new String(sun.nio.Files.readAllBytes(fp));
String fp_pretty = format(fp_contents);
Files.write(fp, fp_pretty.getBytes());
}
}
}

然后我们要有一个 Plugin 类来注册这个 Task,groovy 会 apply from 'path.to.class' 来 Apply 一个 Plugin 到 RootProject

class XmlFormatterPlugin extends SimplePlugin {
@Override
public void apply(Project proj) {
final FormatTask ftask = new FormatTask(getXmlFileTree(proj));
proj.getTasks().create("format-layout", "Format Android XML Layout resources", ftask);
}

private static ConfigurableFileTree getXmlFileTree(Project proj) { return proj.fileTree(makeFileTreeArg(".", "**/*.xml")); }

private static HashMap<String, String> makeFileTreeArg(String dir, String include) {
HashMap<String, String> argt = new HashMap<>();
argt.put("dir", dir); argt.put("include", include);
return argt;
}
}

平铺直叙,毫无 ABC(Assignment、Branches、Conditions)
这才是我不想写太多应用的理由... 有时候真的是我没有时间写应用
其次是现在写这些没意思
默写错(做其他开放定义的修改后没错的除外)的有:

FormatTask#run 可能抛出未捕获的异常 IOException,但是没有标记

XmlFormatterPlugin 使用了 A 类实例 Project#getTasks()
但是 A 类没有 create(String, String, Task): void 这个方法(但是有 create(String, Class<? extends Task>, Consumer<? extends Task>): void

Project#fileTree(Map<String, String>) 的第一个参数是 List 而非 Map
.... 还有些名字的错误,不过 IDE 都可以解决了
你 block 了也没有用... 他又不看,我的处理方式就是直接 ignore 掉,和你意见性格不合的人可能很多,不喜欢直接不交往即可

反正我这个人也天生隔绝交往.... 😭
duangsuse::Echo
Python files/lines/code/doc/blanks 6 / 1372 / 1020 / 100 / 252 一个 GIMP 插件,欲安装请速 INSTALL 待会会有功能展示和使用帮助
This media is not supported in your browser
VIEW IN TELEGRAM
跪求 star.... 好歹我也熬了两天夜啊