发布时间:2025-12-10 19:15:24 浏览次数:6
JavaSe教程「建议收藏」1、java简单概述java是一门面向对象的语言,由sun公司Green项目小组的帕特里克、詹姆斯·高斯林、麦克·舍林丹开发出来的,前期java语言的名字叫做Oak,后面在注册商标的时候发现Oak这名字被占用又更名为java语言,于1995年5月23日java语言正式问世。java语言的特点Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点。2、java开发环境搭建(1)首先按住win+r键输入cmd进入命令行窗口,在里面输入java-varsio
1、java简单概述
2、开发环境搭建
3、开发工具
4、变量
5、运算符
6、输入输出
7、流程控制语句
8、面向对象编程
9、数组
10、数字和字符串
11、日期对象
java是一门面向对象的语言,由sun公司Green项目小组的帕特里克、詹姆斯·高斯林、麦克·舍林丹开发出来的,前期java语言的名字叫做Oak,后面在注册商标的时候发现Oak这名字被占用又更名为java语言,于1995年5月23日java语言正式问世。
java语言的特点
Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点 。
java的注释
//单行注释
/*/多行注释
/ */文档注释
(1)首先按住win+r键输入cmd进入命令行窗口,在里面输入java -varsion 没安装的话会出现如下所示
接下来我们来进行安装
(2)下载jdk
百度搜索 https://www.oracle.com/index.html
找到Developers点进去
无论长路与还是短路与,两边的运算单元都是布尔值,都为真时,才为真,任意为假,就为假。
区别
长路与 两侧,都会被运算
短路与 只要第一个是false,第二个就不进行运算了
|| 长路或 |短或
无论长路或还是短路或,两边的运算单元都是布尔值,都为假时,才为假,任意为真,就为真
区别
长路或 两侧都会被运算。
短路或 只要第一个是true的,第二个就不进行运算了。
用来判断两个对象是否相等,默认比较对象的内存地址。
因为equals没有重写所以默认比较的是内存地址,返回false
package com.oop;public class equalss { String name;int age;public equalss(String name,int age) { this.name=name;this.age=age;}public static void main(String[] args) { equalss e1 = new equalss("张三", 20);equalss e2 = new equalss("张三", 20);System.out.println(e1.equals(e2));}}运行结果false重写了equals之后比较的是内容所以返回true,记得重写了equals方法必须重写hashcode方法。
如果重写equals后,如果不重写hashcode,则hashcode就是继承自Object的,返回内存编码,这时候可能出现equals相等,而hashcode不等,你的对象使用集合时,就会等不到正确的结果
package com.oop;public class equalss { String name;int age;/*重写equals*/@Overridepublic boolean equals(Object obj) { if(obj instanceof equalss) { equalss e = (equalss)obj;if(this.name.equals(e.name)) { return true;}if (this.age==e.age) { return true;}}return false;}/*重写hashcode*/@Overridepublic int hashCode() { int hash = 17;hash = hash*31+name.hashCode();hash = hash*31+age;return hash;}public equalss(String name,int age) { this.name=name;this.age=age;}public static void main(String[] args) { equalss e1 = new equalss("张三", 20);equalss e2 = new equalss("张三", 20);System.out.println(e1.hashCode());System.out.println(e2.hashCode());System.out.println(e1.equals(e2));}}运行结果2403791624037916true所有的类都有toString方法。
toString()的意思是字符串的形式返回当前对象的信息。
package com.oop;public class toStrings { public String name;@Overridepublic String toString() { // TODO Auto-generated method stubreturn "name="+name;}public static void main(String[] args) { toStrings t = new toStrings();System.out.println(new toStrings().name="张三".toString());}}运行结果张三当一个对象没有任何引用指向的时候,它就满足垃圾回收的条件
当它被垃圾回收的时候,它的finalize() 方法就会被调用。
package com.oop;import com.lc.fori;public class finalz { @Overrideprotected void finalize() throws Throwable { System.out.println("回收对象...............");}public static void main(String[] args) { finalz finalz = new finalz();//对象指向null满足垃圾回收机制finalz=null;//调用垃圾回收方法System.gc();}}运行结果回收对象...............单例模式又叫做 Singleton模式,指的是一个类,在一个JVM里,只有一个实例存在,也就是说只能实例化一个对象。
饿汉单例模式
通过调用getInstance方法创建一个对象,每一次是获取同一个对象,无论如何都会创建一个对象。
package com.oop;public class danli { //私有化构造方法使得在外部无法实例化对象int count =0;private danli () { count++;System.out.println("无参构造方法被调用了:"+count+"次");}//准备一个类属性指向实例化对象,因为类属性只有一个private static danli dan =new danli();public static danli getInstance() { return dan;}public static void main(String[] args) { danli dan = danli.getInstance();danli dan1 = danli.getInstance();}}运行结果无参构造方法被调用了:1次懒汉单例模式
package com.oop;public class danli { //私有化构造方法使得该类无法在外部通过new 进行实例化 private danli(){ } //准备一个类属性,用于指向一个实例化对象,但是暂时指向null private static danli instance; //public static 方法,返回实例对象 public static danli getInstance(){ //第一次访问的时候,发现instance没有指向任何对象,这时实例化一个对象 if(null==instance){ instance = new danli(); } //返回 instance指向的对象 return instance; } }直接new会报错
通过getinstace方法才能实例化,并且实例化的是同一个对象。
static是一个关键字可以用来修饰变量、方法、代码块等。
在java当中凡是被static修饰的都是与类相关,可以直接通过类名.访问相对应的变量、方法、代码块。
static修饰变量和方法
static修饰代码块
从以下代码看出来static修饰的代码块优先级高于main方法。
保存一个数据我们可以使用变量进行保存,当我们保存多个数据的时候变量就不能满足我们的需求了,我们可以使用数组来进行多个数据的保存。
数组就是一个固定长度包含了相同类型的数据容器。
当我们创建一个数组,jvm会在内存开辟一个内存空间用来保存数据。
分配空间并同时赋值
//第一种写法int [] arr = { 1,2,3};//第二种写法int []arr = new int []{ 1,2,3};//第三种写法int []arr = new int [3]{ 1,2,3};分配完空间再赋值
int [] arr = new int [2];arr[0] = 1;arr[1] = 2;arr[2] = 3;在java当中我们通过数组的下标对数组元素进行访问,下标从0开始。
假如我们这里有个数组:int [] arr ={1,2,3};
这个数组的长度为3,下标因为是从0开始的,所以他的最大下标是2.
package com.arr;public class arr1 { public static void main(String[] args) { //创建一个数组长度为4int [] arr = { 10,20,30,40};//取数组最后一个下标的值,也就是3System.out.println(arr[3]);}}结果:40数组有一个length表示数组的长度
优点:可以通过索引值访问任何的数组元素, 可以实现随机的访问。
缺点:插入/删除元素时, 需要扩容, 复制或者移动大量的元素, 效率比较低。
应用场景:适用于以查询访问为主, 很少进行插入/删除操作的情况。
变长参数
可变长参数用来接收任意个数据
方法名( 参数类型 参数名, 参数类型 ... 可变长参数名)*规则:
(1) 可变长参数最多只能有一个 (2) 方法参数列表如果有多个参数, 可变长参数只能放在参数列表的最后 (3) 在方法体中, 可以把可变长参数当作数组使用 (4) 在调用方法时,可以传递任意个数, 也可以传递一个数组当我们定义好一个数组并分配好空间之后,数组的长度就是固定了的,如果我们想在数组中存放更多的数据,就需要对数组进行扩容。
package com.arr;public class kuorong { /** * 数组的扩容 * @param args */public static void main(String[] args) { //定义一个数组并分配空间int [] array = new int[5];System.out.println("array数组扩容前的长度是:"+array.length);//定义一个比原数组的空间大的新数组//假设将新数组扩容1.5倍int newarr [] = new int [array.length * 3/2];//把原来数组的内容复制到新数组for (int i = 0; i < array.length; i++) { newarr[i] = array[i];}//把原来数组指向新的数组array=newarr;System.out.println("array数组扩容后的长度是:"+array.length);}}输出结果array数组扩容前的长度是:5array数组扩容后的长度是:7数组元素是一个对象, 数组中存储的是引用类型数据
数组元素实际上存储的是对象的引用
package com.arr;public class Person { private String name;private String sex;public Person(String name, String sex) { super();this.name = name;this.sex = sex;}public void eat() { System.out.println(name+","+sex+"正在吃饭。。。。");}public static void main(String[] args) { //创建一个对象数组Person [] persons = new Person[3];//为对象数组赋值persons[0]= new Person("张三", "男");persons[1]= new Person("李四", "男");persons[2]= new Person("王二", "男");//遍历对象数组for (int i = 0; i < persons.length; i++) { //让数组的每一个人都能吃到饭persons[i].eat();}}}运行结果张三,男正在吃饭。。。。李四,男正在吃饭。。。。王二,男正在吃饭。。。。冒泡排序
思路:从前向后两两比较,如果前面的数大于后面的数就交换,如果有n个数,需要比较n-1轮。
假设有一个数组:int [] arr = {50,30,10};
进行第一轮比较:50大于30,交换到30的后面 30,50,10
50大于10,交换到10的后面
第一轮排序结果为:30,10,50
进行第二轮比较:30大于10,30移动到10的后面
排序结果为10,30,50
package com.arr;public class maopao { public static void main(String[] args) { int [] arr = { 10,30,5,8,2};//外层for循环获得arr数组的长度for (int i = 0; i < arr.length; i++) { //内层循环控制数组循环比较的次数for (int j = 0; j < arr.length-1-i; j++) { //如果左边的值大于右边的值就往后移if(arr[j]>arr[j+1]) { int temp = arr[j];arr[j]= arr[j+1];arr[j+1]= temp;}}}/*打印排序的结果*/for (int i : arr) { System.out.println(i);}}}二维数组,里面的每一个元素,都是一个一维数组,所以二维数组又叫数组的数组。
Arrays是针对数组的工具类,可以进行 排序,查找,复制填充等功能。 大大提高了开发人员的工作效率。
package com.arr;import java.util.Arrays;public class gongju { public static void main(String[] args) { int arr [] = { 10,20,30,100,5,2,1};/*使用工具类对数组进行排序*/Arrays.sort(arr);/*相当于遍历数组*/System.out.println(Arrays.toString(arr));/*用工具类赋值数组*///Arrays.copyOfRange(original, from, to)//original-原数组 from-开始位置 to-结束位置int [] newarr =Arrays.copyOfRange(arr, 0, 6);System.out.print("复制过后的新数组:");System.out.println(Arrays.toString(arr));//查找数组元素的位置//搜索之前先排序Arrays.sort(arr);//数字30出现的位置System.out.println("数字30出现的位置"+Arrays.binarySearch(arr, 30));}}简单来说装箱就是把基本类型数据转换成包装类,拆箱就是把包装类转换成基本类型数据。
每个基本类型数据都有对应得包装类。
| number类型 | 包装类 |
|---|---|
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| boolean类型 | 包装类 |
|---|---|
| boolean | Boolean |
| 字符型 | 包装类 |
|---|---|
| char | Character |
package com.api;public class baozhuang { public static void main(String[] args) { //装箱 --包基本类型数据转换成包装类int i = 100;Integer j = new Integer(i);System.out.println(j);//拆箱 --包装类转换成基本类型Double d = new Double(50.0);double d1 = d.intValue();System.out.println(d1);//自动装箱、拆箱 --不需要调用构造方法 通过= 进行自动装箱、拆箱//自动装箱float f = 10f;Float f1 = f;System.out.println(f1);//自动拆箱Character c = 'a';char c1 = c;System.out.println(c1);}}运行结果
10050.010.0ajava.lang.Math提供了一些常用的数学运算方法,并且都是以静态方法的形式存在。
package com.api;import java.util.Random;public class strings { public static void main(String[] args) { double i = 4.6;//Math.round() 四舍五入System.out.println(Math.round(i));//Math.random() 取一个0到1之间得随机浮点数,取不到取1System.out.println(Math.random());//Math.random()*10 取一个1到10之间得随机整数,取不到取10int r =((int)(Math.random()*10));System.out.println(r);int j = 100;//Math.abs() 求绝对值System.out.println(Math.abs(j));// Math.acos() 返回三角余弦double d = 50;System.out.println(Math.acos(d));// Math.pow(参数1, 参数2)返回第一个参数的第二个参数次幂的值。double d1 = 10,d2=3;//10得3次幂System.out.println(Math.pow(d1, d2));//Math.sqrt()返回正确舍入的 double 值的正平方根System.out.println(Math.sqrt(9));}}运行结果
50.228215664983644984100NaN1000.03.0package com.api;public class characters { public static void main(String[] args) { //character字符操作//判断是否是一个字符,是返回true,不是返回falseSystem.out.println(Character.isLetter('a'));//判断是否是数字,是返回true,不是返回falseSystem.out.println(Character.isDigit('s'));//判断字符是否是大写,是返回true,不是返回falseSystem.out.println(Character.isUpperCase('S'));//判断字母是否是小写,是返回true,不是返回falseSystem.out.println(Character.isLowerCase('s'));//转换成小写System.out.println(Character.toLowerCase('A'));//小写转换成大写System.out.println(Character.toUpperCase('a'));}}运行结果
truefalsetruetrueaA字符串是不可继承,字符串是一个常量是不可改变得。
当给String类型得变量赋值,虚拟机会创建一个字符串对象。
package com.api;public class String1 { public static void main(String[] args) { //给字符串变量赋值时,虚拟机会根据值创建一个字符串对象String str = "字符串";//创建字符串对象String str1 = new String("字符串1");//字符串品拼接也会创建一个字符串对象String str2 = str + str1;System.out.println(str2);}}运行结果
字符串1如果字符串不格式化就需要进行哦拼接,一旦变量多就会变得繁琐,所以我们可以使用字符串格式化来完成这项操作。
%s表示字符串,%d表示数字,%n表示换行
package com.api;public class String1 { public static void main(String[] args) { String name ="张三";int age = 20;String form = "我叫%s,今年%d岁";System.out.println(String.format(form, name,age));}}运行结果
我叫张三,今年20岁package com.api;public class czZfc { public static void main(String[] args) { //charAt(int index)获取指定位置的字符,下标从0开始String str = "helloword";System.out.println("截取指定位置得字符串为:"+str.charAt(4));//toCharArray() 将字符串转换成数组char[] charArray = str.toCharArray();for (int i = 0; i < charArray.length; i++) { System.out.print(charArray[i]+"\t");}System.out.println();//subStriing() 截取字符串System.out.print("截取得字符串为:"+str.substring(0, 2));System.out.println();//分割字符串 split(以什么形式分割)String str2 = "你好啊,世界,每天爱你多一点哦";//以,得形式分割String[] split = str2.split(",");for (int i = 0; i < split.length; i++) { System.out.println(split[i]);}//去掉空格 trim() 只去掉首位空格String str3 = " gfhjsdgfsd ";System.out.println(str3.trim());//将字符转换成大写、小写String str4 = "asfasfasf";//转成大写System.out.println(str4.toUpperCase());//转成小写System.out.println(str4.toLowerCase());//查找字符串//index Of() 字符串第一次出现得位置//last indexOf()字符串最后一次出现得位置//contains 是否包含子字符串String str5 = "爱我中华!";System.out.println("字符串第一次出现得位置是:"+str5.indexOf("我"));System.out.println("字符串最后一次出现得位置是:"+str5.lastIndexOf("华"));System.out.println("字符串是否被包含:"+str5.contains("a"));//字符串替换//replaceAll 替换所有的//replaceFirst 只替换第一个String str6 = "asbjaksfbhajskf";//将所有得f替换成qSystem.out.println(str6.replaceAll("f", "q"));System.out.println(str6.replaceFirst(",",""));}}运行结果
截取指定位置得字符串为:ohelloword截取得字符串为:he你好啊世界每天爱你多一点哦gfhjsdgfsdASFASFASFasfasfasf字符串第一次出现得位置是:1字符串最后一次出现得位置是:3字符串是否被包含:falseasbjaksqbhajskqasbjaksfbhajskfpackage com.api;public class bijiao { public static void main(String[] args) { //==比较字符串String str1 = "abc";String str2 = new String("abc");//结果为false是因为==比较得是内存地址System.out.println(str1==str2);String str3 = "zxc";String str4 = "zxc";//结果为true是因为 字符串在赋值得时候会创建一个String对象//当创建第二个对象得时候发现该字符串对象存在可以拿来直接使用,所以不会创建新得String对象System.out.println(str3==str4);//equals比较内容是否相同System.out.println(str3.equals(str4));//判断字符串以什么开头,以什么结尾String str6 = "abcd";System.out.println(str6.startsWith("a"));System.out.println(str6.endsWith("d"));}}运行结果
falsetruetruetruetruejava.lang.StringBuffer
因为String(字符串)是不可变得,所以我们要使用StringBuffer处理字符串,StringBuffrer()是可变字符串可以随意增删改查,并且容量会自动扩大。
package com.api;public class StringBuffers { public static void main(String[] args) { String str = "";StringBuffer sBuffer = new StringBuffer(str);//append()追加字符串sBuffer.append("你好啊,世界!");System.out.println(sBuffer);//删除初始位置到指定位置的字符串sBuffer.delete(0, 2);System.out.println(sBuffer);//删除指定位置的字符串sBuffer.deleteCharAt(1);System.out.println(sBuffer);//在指定的位置插入字符串sBuffer.insert(4, "你好啊");System.out.println(sBuffer);//字符串反转sBuffer.reverse();System.out.println(sBuffer);}}运行结果
你好啊,世界!啊,世界!啊世界!啊世界!你好啊啊好你!界世啊StringBuilder 类是 JDK 1.5 新增的类,功能和StringBuffer差不多,不同的是StringBuilder没有实现线程安全,所以是线程不安全的,如果要创建可变字符串优先使用StringBuffer,速度方面因为StringBuilder去掉了保证线程安全的那部分,减少了开销,所以比SttingBuffer快一些,但是不是绝对的。
在使用方面
操作少量的数据使用 String。
单线程操作大量数据使用 StringBuilder。
多线程操作大量数据使用 StringBuffer。
# 11、日期对象
java.util.Date;
所有的数据在计算机最后逗得以数字形式表示出来,日期也不例外,零这个数字,就代表Java中的时间原点,其对应的日期是1970年1月1日 8点0分0秒 。 (为什么是8点,因为中国的太平洋时区是UTC-8,刚好和格林威治时间差8个小时),因为1969年发布了第一个 UNIX 版本:AT&T,综合考虑,当时就把1970年当做了时间原点,所有的日期,都是以为这个0点为基准,每过一毫秒,就+1。
创建日期对象
package com.api;import java.util.Date;public class dates { public static void main(String[] args) { //创建日期对象Date date = new Date();System.out.println(date);// // 从1970年1月1日 早上8点0分0秒 开始经历的毫秒数Date date2 = new Date(10000);System.out.println("从1970年1月1日 早上8点0分0秒 开始经历了10秒时间");//get time以long型整数得到当前时间System.out.println(date.getTime());//和gettime一样得到当前日期的毫秒数System.out.println(System.currentTimeMillis());}}运行结果
Thu Aug 27 09:06:06 CST 2020从1970年1月1日 早上8点0分0秒 开始经历了10秒时间15984903667251598490366753日期格式化
通过 SimpleDateFormat 将日期格式化。
package com.api;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.logging.SimpleFormatter;public class sim { public static void main(String[] args) throws ParseException { //y 代表年//M 代表月//d 代表日//H 代表24进制的小时//h 代表12进制的小时//m 代表分钟//s 代表秒//S 代表毫秒//创建日期格式化类,根据构造方法填入相对应的值SimpleDateFormat sim = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");//创建日期对象Date date = new Date();//通过format方法将当前日期以字符串的形式进行输出System.out.println(sim.format(date));String str = "2020年08月27日 17时07分30秒";Date parse = sim.parse(str);System.out.println(parse.toString());}}运行结果
2020年08月27日 09时18分23秒Thu Aug 27 17:07:30 CST 2020Calendar常用于对日历的操作。
创建Calendar对象获取当前时间
package com.api;import java.util.Calendar;import java.util.Date;public class calendar { public static void main(String[] args) { //通过单例模获取当前对象Calendar cl = Calendar.getInstance();System.out.println(cl);}}运行结果
java.util.GregorianCalendar[time=1598491418827,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[,offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2020,MONTH=7,WEEK_OF_YEAR=35,WEEK_OF_MONTH=5,DAY_OF_MONTH=27,DAY_OF_YEAR=240,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=4,AM_PM=0,HOUR=9,HOUR_OF_DAY=9,MINUTE=23,SECOND=38,MILLISECOND=827,ZONE_OFFSET=28800000,DST_OFFSET=0]package com.api;import java.util.Calendar;import java.util.Date;public class calendar { public static void main(String[] args) { //通过单例模获取当前对象Calendar cl = Calendar.getInstance();//获得当前时间System.out.println(cl.getTime());//获得当前年份int year = cl.get(Calendar.YEAR);System.out.println("当前年份是:"+year+"年");//获得当前月份(月份从0开始所以要加1)int month = cl.get(Calendar.MONTH)+1;System.out.println("现在是:"+month+"月");//获取日int day = cl.get(Calendar.DATE);System.out.println("现在是:"+day+"日");//获取今天是星期几,以星期日为第一天所以要-一天int week = cl.get(Calendar.DAY_OF_WEEK)-1;System.out.println("今天是星期:"+week);// 获取当前小时数(24 小时制)int hour = cl.get(Calendar.HOUR_OF_DAY); System.out.println(hour + "时");System.out.println("星期" + week);// 获取当前分钟System.out.println(hour + "时");int minute = cl.get(Calendar.MINUTE); System.out.println(minute + "分");// 获取当前秒数int second = cl.get(Calendar.SECOND); System.out.println(second + "秒");// 获取毫秒数int millisecond = cl.get(Calendar.MILLISECOND); System.out.println(millisecond + "毫秒");// 获取今天是本月第几天int dayOfMonth = cl.get(Calendar.DAY_OF_MONTH); System.out.println("今天是本月的第 " + dayOfMonth + " 天");// 获取今天是本月第几周int dayOfWeekInMonth = cl.get(Calendar.DAY_OF_WEEK_IN_MONTH); System.out.println("今天是本月第 " + dayOfWeekInMonth + " 周");// 获取今天是今年第几天int many = cl.get(Calendar.DAY_OF_YEAR); System.out.println("今天是今年第 " + many + " 天");// 设置年月日,时分秒将默认采用当前值cl.set(2012, 8, 8);System.out.println("设置日期为 2012-8-8 后的时间:" + cl.getTime());}}运行时间
Thu Aug 27 09:40:18 CST 2020当前年份是:2020年现在是:8月现在是:27日今天是星期:49时星期49时40分18秒611毫秒今天是本月的第 27 天今天是本月第 4 周今天是今年第 240 天设置日期为 2012-8-8 后的时间:Sat Sep 08 09:40:18 CST 2012Calendar对象打印万年历
package com.api;import java.util.Calendar;import java.util.Scanner;public class SRRLTest { public static void main(String[] args) { Scanner sc = new Scanner(System.in);Calendar cal = Calendar.getInstance();System.out.println("请输入年份:");int year = sc.nextInt();System.out.println("请输入月份:");int month = sc.nextInt()-1;cal.set(Calendar.YEAR,year);cal.set(Calendar.MONTH,month);System.out.println("日\t一\t二\t三\t四\t五\t六");//得到这个月1号星期几int dayofmonth = cal.get(Calendar.DAY_OF_MONTH);cal.add(Calendar.DATE , - dayofmonth +1);int xq = cal.get(Calendar.DAY_OF_WEEK);//打空格for (int i = 0; i <xq-1 ; i++) { System.out.print("\t");}//这个月的天数int start =cal.get(Calendar.DAY_OF_YEAR);cal.add(Calendar.MONTH,1);int end = cal.get(Calendar.DAY_OF_YEAR);int day = end - start;//打日期数字的for (int i = 1; i <=day ; i++) { System.out.print(i+"\t");if ((i+xq-1)%7==0){ System.out.println();}}}}运行结果