java转移 u0019_变量-Java为什么在其标识符中允许使用控制字符?

在精确地探究Java标识符中允许使用哪些字符时,我偶然发现了一件非常奇怪的事情,以至于几乎可以肯定这是一个错误。

我希望发现Java标识符符合以下要求:它们以具有Unicode属性Current_Symbol的字符开头,然后是具有ID_Continue的字符,但下划线和美元符号除外。 事实并非如此,我发现与我所听说的那种普通标识符或其他任何想法都存在极大差异。

简短演示

请考虑以下演示,证明Java标识符中允许使用ASCII ESC字符(八进制033):

$ perl -le 'print qq(public class escape { public static void main(String argv[]) { String var_\033 = "i am escape: \033"; System.out.println(var_\033); }})' > escape.java

$ javac escape.java

$ java escape | cat -v

i am escape: ^[

不过,甚至比那更糟。 实际上,几乎无限恶化。 甚至允许NULL! 还有成千上万个甚至不是标识符字符的代码点。 我已经在Solaris,Linux和运行Darwin的Mac上进行了测试,所有结果均相同。

长演示

这是一个测试程序,它将显示Java完全允许作为合法标识符名称的一部分的所有这些意外代码点。

#!/usr/bin/env perl

#

# test-java-idchars - find which bogus code points Java allows in its identifiers

#

# usage: test-java-idchars [low high]

# e.g.: test-java-idchars 0 255

#

# Without arguments, tests Unicode code points

# from 0 .. 0x1000. You may go further with a

# higher explicit argument.

#

# Produces a report at the end.

#

# You can ^C it prematurely to end the program then

# and get a report of its progress up to that point.

#

# Tom Christiansen

# tchrist@perl.com

# Sat Jan 29 10:41:09 MST 2011

use strict;

use warnings;

use encoding "Latin1";

use open IO => ":utf8";

use charnames ();

$| = 1;

my @legal;

my ($start, $stop) = (0, 0x1000);

if (@ARGV != 0) {

if (@ARGV == 1) {

for (($stop) = @ARGV) {

$_ = oct if /^0/; # support 0OCTAL, 0xHEX, 0bBINARY

}

}

elsif (@ARGV == 2) {

for (($start, $stop) = @ARGV) {

$_ = oct if /^0/;

}

}

else {

die "usage: $0 [ [start] stop ]\n";

}

}

for my $cp ( $start .. $stop ) {

my $char = chr($cp);

next if $char =~ /[\s\w]/;

my $type = "?";

for ($char) {

$type = "Letter" if /\pL/;

$type = "Mark" if /\pM/;

$type = "Number" if /\pN/;

$type = "Punctuation" if /\pP/;

$type = "Symbol" if /\pS/;

$type = "Separator" if /\pZ/;

$type = "Control" if /\pC/;

}

my $name = $cp ? (charnames::viacode($cp) || "") : "NULL";

next if $name eq "" && $cp > 0xFF;

my $msg = sprintf("U+%04X %s", $cp, $name);

print "testing \\p{$type} $msg...";

open(TESTPROGRAM, ">:utf8", "testchar.java") || die $!;

print TESTPROGRAM <

public class testchar {

public static void main(String argv[]) {

String var_$char = "variable name ends in $msg";

System.out.println(var_$char);

}

}

End_of_Java_Program

close(TESTPROGRAM) || die $!;

system q{

( javac -encoding UTF-8 testchar.java \

&& \

java -Dfile.encoding=UTF-8 testchar | grep variable \

) >/dev/null 2>&1

};

push @legal, sprintf("U+%04X", $cp) if $? == 0;

if ($? && $? < 128) {

print "\n";

exit; # from a ^C

}

printf "is %s in Java identifiers.\n",

($? == 0) ? uc "legal" : "forbidden";

}

END {

print "Legal but evil code points: @legal\n";

}

这是仅在前三个代码点(既不是空格也不是标识符字符)上运行该程序的示例:

$ perl test-java-idchars 0 0x20

testing \p{Control} U+0000 NULL...is LEGAL in Java identifiers.

testing \p{Control} U+0001 START OF HEADING...is LEGAL in Java identifiers.

testing \p{Control} U+0002 START OF TEXT...is LEGAL in Java identifiers.

testing \p{Control} U+0003 END OF TEXT...is LEGAL in Java identifiers.

testing \p{Control} U+0004 END OF TRANSMISSION...is LEGAL in Java identifiers.

testing \p{Control} U+0005 ENQUIRY...is LEGAL in Java identifiers.

testing \p{Control} U+0006 ACKNOWLEDGE...is LEGAL in Java identifiers.

testing \p{Control} U+0007 BELL...is LEGAL in Java identifiers.

testing \p{Control} U+0008 BACKSPACE...is LEGAL in Java identifiers.

testing \p{Control} U+000B LINE TABULATION...is forbidden in Java identifiers.

testing \p{Control} U+000E SHIFT OUT...is LEGAL in Java identifiers.

testing \p{Control} U+000F SHIFT IN...is LEGAL in Java identifiers.

testing \p{Control} U+0010 DATA LINK ESCAPE...is LEGAL in Java identifiers.

testing \p{Control} U+0011 DEVICE CONTROL ONE...is LEGAL in Java identifiers.

testing \p{Control} U+0012 DEVICE CONTROL TWO...is LEGAL in Java identifiers.

testing \p{Control} U+0013 DEVICE CONTROL THREE...is LEGAL in Java identifiers.

testing \p{Control} U+0014 DEVICE CONTROL FOUR...is LEGAL in Java identifiers.

testing \p{Control} U+0015 NEGATIVE ACKNOWLEDGE...is LEGAL in Java identifiers.

testing \p{Control} U+0016 SYNCHRONOUS IDLE...is LEGAL in Java identifiers.

testing \p{Control} U+0017 END OF TRANSMISSION BLOCK...is LEGAL in Java identifiers.

testing \p{Control} U+0018 CANCEL...is LEGAL in Java identifiers.

testing \p{Control} U+0019 END OF MEDIUM...is LEGAL in Java identifiers.

testing \p{Control} U+001A SUBSTITUTE...is LEGAL in Java identifiers.

testing \p{Control} U+001B ESCAPE...is LEGAL in Java identifiers.

testing \p{Control} U+001C INFORMATION SEPARATOR FOUR...is forbidden in Java identifiers.

testing \p{Control} U+001D INFORMATION SEPARATOR THREE...is forbidden in Java identifiers.

testing \p{Control} U+001E INFORMATION SEPARATOR TWO...is forbidden in Java identifiers.

testing \p{Control} U+001F INFORMATION SEPARATOR ONE...is forbidden in Java identifiers.

Legal but evil code points: U+0000 U+0001 U+0002 U+0003 U+0004 U+0005 U+0006 U+0007 U+0008 U+000E U+000F U+0010 U+0011 U+0012 U+0013 U+0014 U+0015 U+0016 U+0017 U+0018 U+0019 U+001A U+001B

这是另一个演示:

$ perl test-java-idchars 0x600 0x700 | grep -i legal

testing \p{Control} U+0600 ARABIC NUMBER SIGN...is LEGAL in Java identifiers.

testing \p{Control} U+0601 ARABIC SIGN SANAH...is LEGAL in Java identifiers.

testing \p{Control} U+0602 ARABIC FOOTNOTE MARKER...is LEGAL in Java identifiers.

testing \p{Control} U+0603 ARABIC SIGN SAFHA...is LEGAL in Java identifiers.

testing \p{Control} U+06DD ARABIC END OF AYAH...is LEGAL in Java identifiers.

Legal but evil code points: U+0600 U+0601 U+0602 U+0603 U+06DD

问题

谁能解释这个看似疯狂的行为? 从U + 0000开始,到处都有很多很多其他莫名其妙允许的代码点,这也许是最奇怪的。 如果在第一个0x1000代码点上运行它,您会看到确实出现了某些模式,例如允许使用属性Current_Symbol允许任何代码点和所有代码点。但是,至少对于我来说,还有太多其他情况是完全无法解释的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
计算机程序设计(Java)-教案--单元二--Java语言开发基础全文共8页,当前为第1页。计算机程序设计(Java)-教案--单元二--Java语言开发基础全文共8页,当前为第1页。课堂教学计划表 计算机程序设计(Java)-教案--单元二--Java语言开发基础全文共8页,当前为第1页。 计算机程序设计(Java)-教案--单元二--Java语言开发基础全文共8页,当前为第1页。 课程名称 Java程序设计 教师姓名 专业班级 授课时间 授课地点 学时数 8 授课题目 §2Java语言开发基础 教学目标及要求 知识目标 掌握Java语言的基本组成; :・掌握数据类型、变量、运算符及表达式; :・掌握三种控制结构; 技能目标 :・培养学生规范编码和良好的程序设计风格; :・能够应用Java语言进行程序设计; 数据类型、运算符、字符串、数组等知识在编程过程能熟练、准确应用; ・:・能熟练、准确地应用分支、循环、跳转三种流程执行过程; 教学重点 :・标识符命名规那么、数据类型与运算符; : 嵌套ifelse语句的用法; 教学难点 :・数值类型转换(强制转换、隐式转换)的用法; :・Switch语句的用法; 工程描述 :・工程1:猜数字游戏 教学方法 问题导引法:通过给学生提出实际编程出现的问题来引入教学内容,使学生在主动分析、讨论和解决问题的过程掌握所学知识; :・案例分析法:通过演示典型案例来讲解相关知识和技术的具体使用过程,使学生在具体的应用环境加深对概念的理解; :・任务驱动法:通过完成工程的各个任务逐步增强实版技能; 教学过程设计 一、新课导入与工程展示 :・首先通过提问、讨论等互动的形式引入课程新知识; : 然后通过演示本章工程来激发学生的学习兴趣,增强学生学习的积极性、主动性; 计算机程序设计(Java)-教案--单元二--Java语言开发基础全文共8页,当前为第2页。计算机程序设计(Java)-教案--单元二--Java语言开发基础全文共8页,当前为第2页。教案正文 计算机程序设计(Java)-教案--单元二--Java语言开发基础全文共8页,当前为第2页。 计算机程序设计(Java)-教案--单元二--Java语言开发基础全文共8页,当前为第2页。 二、工程任务分解 ・:・带着学生分析本章工程并对工程进行任务分解,各工程分解任务如下: 工程1:猜数字游戏 ,任务1:确定变量 /任务2:选择数据类型 /任务3:确定表达式 /任务4:循环猜数,并统计次数 三、任务分析 :・根据工程及任务的描述和要求,对工程的各个任务进行分析,然后总结出完成该任务所需要的知识、技能和主要操作步骤; 四、相关知识点 :・针对各个任务分析阶段得到的知识和技能,并结合本章知识和技能目标对相关知识点进行详细讲解和说明; 五、任务实施 :・该阶段以完成各个任务为目的,教师利用相关知识和技能以演示的方式为学生详细讲解每个任务的完整实现过程; :・同时,该阶段要求学生进行跟随练习,以加深对知识和技能的理解和掌握; 六、技能拓展 :・在保证学生掌握了各个任务所涉及的基本知识和技能的基础上,再通过介绍一定的附加知识并辅导学生完成指定的"技能拓展任务",最终使学生对所学知识到达举一反三,融会贯通的学习目的; 七、指导与评价 对学生的任务实施过程进行指导,并对其出现的问题进行总结,给出评价; 课后作业 :・完成课后相关习题; 课后分析 :・主要问题: 面向对象思、想的培养; 一、新课导入与工程展示思考:回顾C语言学过的基本语法知识? 计算机程序设计(Java)-教案--单元二--Java语言开发基础全文共8页,当前为第3页。计算机程序设计(Java)-教案--单元二--Java语言开发基础全文共8页,当前为第3页。运行各个源程序,为学生演示本章工程各个任务的实现效果。 计算机程序设计(Java)-教案--单元二--Java语言开发基础全文共8页,当前为第3页。 计算机程序设计(Java)-教案--单元二--Java语言开发基础全文共8页,当前为第3页。 二、工程任务分解本章工程可以划分为以下主要任务: 工程1:猜数字游戏任务1:确定变量任务2:选择数据类型任务3:确定表达式 任务4:循环猜数,并统计次数 三、任务1・1:确定变量 任务分析 猜数游戏需要计算机产生随机数,还需要用户输入猜测的数字。 本任务就是要确定用哪些变量来保存这些数据,并且如何命名变量。 相关知识点 (1)标识符 Java的包名、类名、方法名、参数名、变量名等都需要用一个符号来标识,这个符号就称为标识符java标识符的命名规那么如下: 组成:可由大小写字母、数字、下划夜(_)和美元符号($) 组成。 开头:必须以字母、下划线或美元符号($)开头。 字母:严格区分字母
常量表示不能改变的数值。 Java常量的分类: 1,整数常量。所有整数 2,小数常量。所有小数 3,布尔(boolean)型常量。较为特有,只有两个数值。true false。 4,字符常量。将一个数字字母或者符号用单引号( ' ' )标识。 5,字符串常量。将一个或者多个字符用双引号(“ ”)标识。 6,null常量。只有一个数值就是:null. 对于整数:有四种表现形式。 •二进制:0,1 ,满2进1. •八进制:0-7 ,满8进1. 用0开头表示。 •十进制:0-9 ,满10进1. •十六进制:0-9,A-F,满16进1. 用0x开头表示。 进制的基本转换 •十进制 二进制 互转 •十进制转成二进制 除以2取余数 •二进制转成十进制 乘以2的幂数 •十进制 八进制 互转 •十进制 十六进制 互转 •负数的二进制表现形式   对应的正数二进制取反加1 变量的概念: •内存的一个存储区域 •该区域有自己的名称(变量名)和类型(数据类型) •该区域的数据可以在同一类型范围内不断变化 为什么要定义变量: •用来不断的存放同一类型的常量,并可以重复使用 使用变量注意: •变量的作用范围(一对{}之间有效) •初始化值 定义变量的格式: •数据类型 变量名 = 初始化值; •注:格式是固定的,记住格式,以不变应万变。 理解:变量就如同数学的未知数。 变量字节大小及有效取值范围 byte占用一个字节,数字大小为-27—27-1 short占用两个字节,数字大小为-215—215-1 int占用四个字节,数字大小为-231—231-1 long占用八个字节,数字大小为-263—263-1 float占用四个字节,数字大小为1.4E-45~3.4E+38 , -1.4E-45~-3.4E+38 。   用二进制的指数形式表示一个浮点数的格式,如:101*22 , 101*2-3 double占用八个字节,数字大小为4.9E-324~1.7E+308, -4.9E-324~-1.7E+308 。 char占两个字节,数字大小为0———216-1,是unicode编码。   字符的本来面目,我们为什么可以直接将一个数字赋给字符变量。 Boolean占一个字节,其取值只有两个,true和false。 等等 详细介绍用法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值