第二天:数据类型转换、运算符、方法

一.数据类型转换

(一)为什么要进行数据类型转换?

Java程序中要求参与的计算的数据,必须要保证数据类型的一致性,如果数据类型不一致将发生类型的转换。

(二)自动类型转换(隐式)

1.特点:

\color{red}{取值范围小}的类型 自动提升为\color{red}{取值范围大}的类型。

  • 当一个byte类型变量和一个int变量运算时,byte类型将会自动提升为int类型进行运算。

代码

public class Change{
    public static void main(String[] args){
        int a = 1;
        byte b = 2;
        // byte x = a + b; // 报错
        //int类型和byte类型运算,结果是int类型
        int x = a + b;
        System.out.println(x);
    }
}

运行结果:

image.png
  • 同样道理,当一个int类型变量和一个double变量运算时,int类型将会自动提升为double类型进行运算。

代码:

public class change{
    public static void main(String[] args){
        int a = 1;
        double b = 2.5;
        //int类型和double类型运算,结果是double类型
        double c = a+b;//int类型会提升为double类型
        System.out.println(c);
    }
}

运行结果:

image.png
2.转换原理图解:

byte类型内存占有1个字节,在和int类型运算时会提升为int类型 ,自动补充3个字节,因此计算后的结果还是int类型。

1.png

3.转换规则:

范围小的类型向范围大的类型提升,byteshortchar运算时直接提升为int
byteshortchar‐‐>int‐‐>long‐‐>float‐‐>double

代码:

public class change{
    public static void main(String[] args){
        byte b1 = 1;
        byte b2 = 2;
        // byte b3 = b1 + b2;//错误写法,byte类型运算时直接提升为int
        int i1 = b1 + b2;//正确写法
        System.out.println(i1);//3

        short s1 = 1;
        short s2 = 2;
        // short s3 = s1 + s2;//错误写法,short类型运算时直接提升int
        int i2 = s1 + s2;//正确写法
        System.out.println(i2);//3

        char c1 = 'A';
        char c2 = 1;
        // char c3 = c1 + c2;//错误写法,char类型运算时直接提升int
        int i3 = c1 + c2;//正确写法
        System.out.println(i3);//66
    }
}

运行结果:

image.png

(三)强制类型转换(显式)

1.特点:

\color{red}{取值范围大}的类型 强制转换成\color{red}{取值范围小}的类型 。

  • 比较而言,自动转换是Java自动执行的,而强制转换需要我们自己手动执行。

代码:

public class Change{
    public static void main(String[] args){
        /*
        double类型内存8个字节,int类型内存4个字节。 
        1.5 是 double 类型,取值范围大于int。
        可以理解为double是8升的水壶,int是4升的水壶。
        不能把大水壶中的水直接放进小水壶去。
        想要赋值成功,只有通过强制类型转换,
        将double类型强制转换成int类型才能赋值。
        */
        // double类型数据强制转成int类型,直接去掉小数点。
        // int i = 1.5;//编译失败
        int i = (int)1.5;
        System.out.println(i);//1

        short s = 1;//short类型变量,内存中2个字节
        /*
        s和1做运算的时候,1是int类型,s会被提升为int类型
        s+1后的结果是int类型,将结果在赋值会short类型时发生错误
        short内存2个字节,int类型4个字节
        必须将int强制转成short才能完成赋值
        */
        // s = s + 1;//编译失败
        s = (short)(s+1);
        System.out.println(s);//2
    }
}

运行结果:

image.png
2.转换格式:
  • 数据类型 变量名 = (数据类型)被转数据值;
  • 例:int i = (int)1.5;
3.转换原理图解:
image.png

(四)注意事项

  • 强制类型转换一般不推荐使用,因为有可能发生精度损失、数据溢出。
    (例:浮点转成整数,直接取消小数点,可能造成数据损失精度。
    int 强制转成 short 砍掉2个字节,可能造成数据丢失。)
  • byte/short/char这三种类型都可以发生数学运算,例如加法“+”.
  • byte/short/char这三种类型在运算的时候,都会被首先提升成为int类型,然后再计算。
  • boolean类型不能发生数据类型转换

(五)编码表(数字和字符的对照关系表)

1.概述:

编码表 :就是将人类的文字和一个十进制数进行对应起来组成一张表格。

2.Java中的编码表:
  • ASCII码表:American Standard Code for Information Interchange,美国信息交换标准代码。
  • Unicode码表:万国码。也是数字和符号的对照关系,开头0-127部分和ASCII完全一样,但是从128开始包含有更多字符。
3.常用编码:
48  -  '0'
65  -  'A'
97  -  'a'

Tips:
char c = 'a';
int i = c + 1;
System.out.println(i)//98
在char类型和int类型计算的过程中,char类型的字符先查询编码表,得到97,再和1求和,结果为98。char类型提升为了int类型。char类型内存2个字节,int类型内存4个字节。

(六)编译器的两点优化(自动进行的强制类型转换)

1.第一点

对于byte/short/char三种类型来说,如果右侧赋值的数值没有超过范围,那么javac编译器将会自动隐含地为我们补上一个(byte) (short) (char).

  • 如果右侧的数值没有超过左侧的范围,编译器补上强转。
  • 如果右侧的数值超过了左侧范围,那么编译器直接报错。

代码:

public class Change{
    public static void main(String[] args){
        //右侧确实是一个int数字,但是没有超过左侧的范围,就是正确的。
        //int --> byte,不是自动类型转换
        byte num = 30; //右侧没有超过左侧的范围,相当于:byte num = (byte)30;
        System.out.println(num);//30

        //int --> char,不是自动类型转换
        char ch = 65; //右侧没有超过左侧的范围,相当于:char ch = (char)65;
        System.out.println(ch);//A
    }
}

运行结果:

image.png
2.第二点
  • 在给变量进行赋值的时候,如果右侧的表达式当中全都是常量,没有任何变量,那么编译器javac将会直接将若干个常量表达式计算得到结果。
  • short result = 5 + 8;1等号右边全都是常量,没有任何变量参与运算,编译之后,得到的.class字节码文件当中相当于 : short result = 13;右侧的常量结果数值,没有超过左侧范围,所以正确。这称为“编译器的常量优化”。
  • 但是注意:一旦表达式当中有变量参与,那么就不能进行这种优化了。

代码:

public class Change{
    public static void main(String[] args){
        byte a = 1;//正确写法,右侧没有超过左侧的范围
        byte b = 2;
        // byte + byte --> int + int --> int
        // byte c1 = b1 + b2;//错误写法,左侧需要是int类型
        // System.out.println(c1);

        //右侧不用变量,而是采用常量,而且只有两个常量,编译器进行常量优化
        byte c2 = 1 + 2;
        System.out.println(c2);//3

        // byte c3 = 1 + a + 2;//错误写法,只有常量时才会进行优化
    }
 }

运行结果:

image.png

二.运算符

(一)算术运算符

1.分类:
+        加法运算,字符串连接运算
-        减法运算
*        乘法运算
/        除法运算
%        取模运算,两个数字相除取余数
++ --    自增自减运算
  • Java中,整数使用以上运算符,无论怎么计算,也不会得到小数。

代码:

public class Operator{
    public static void main(String[] args){
        int i = 1234;
        System.out.println(i/1000*1000);//计算结果是1000
    }
}

运行结果:

image.png
2.+的多种用途:

(1) 对于数值来说,那就是加法。
(2) 对于字符char类型来说,在计算之前,char会被提升成为int,然后再计算。(char类型字符和int类型数字之间的对照关系表:ASCII、Unicode)
(3) 对子字符串String(首字母大写,并不是关键字)来说,加号代表字符串连接操作。(任何数据类型和字符串进行连接的时候,结果都会变成字符串)

代码:

public class Operator{
    public static void main(String[] args){
        String str1 = "Hello";
        System.out.println(str1);//Hello
        //字符串连接
        System.out.println(str1 + "World");//HelloWorld

        String str2 = "Java";
        //String + int --> String
        System.out.println(str2 + 20);//Java20

        //优先级问题
        //String + int + int
        //String       + int
        //String
        System.out.println(str2 + 20 + 30);//Java2030
        System.out.println(str2 + (20 + 30));//Java50

    }
}

运行结果:

image.png
3.自增自减运算符++ --:

(1)基本含义:
让一个变量涨一个数字1,或者让一个变量降一个数字1
(2)使用格式:
写在变量名称之前,或者写在变量名称之后。例如;++num,也可以num++
(3)使用方式:

  • 单独使用:不和其他任何操作混合,自己独立成为一个步骤。
  • 混合使用:和其他操作混合,例如与赋值混合,或者与打印操作混合等。

(4)使用区别:

  • 在单独使用的时候,前++和后++没有任何区别。也就是:++num;和num++;是完全一样的。
  • 在混合的时候,有【重大区别】
    A.如果是前++,那么变量【立刻马上+1】,然后拿着结果进行使用。\color{red}{【先加后用】}
    B.如果是后++,那么首先使用变量本来的数值,【然后再让变量+1】。\color{red}{【先用后加】}

代码:

public class Operator{
    public static void main(String[] args){
        int a = 1;
        int b = ++a;//a=2,b=2
        int c = a++;//a=3,c=2
        int d = a++ + ++a;//a=5,d=3+5=8
        System.out.println(a);//5
        System.out.println(b);//2
        System.out.println(c);//2
        System.out.println(d);//8
    }
}

运行结果:

image.png

(5)注意事项:

  • 只有变量才能使用++ --,常量不可以。
  • 自增自减运算符隐含了一个强制类型转换

代码:

public class Operator{
    public static void main(String[] args){
        //30++;//错误写法,常量不可以使用++或者--
        byte a = 1;
        // byte b = a + 1;//错误用法,会报错
        byte b = ++a;//相当于byte b = (byte)++a;
        byte c = --a;//相当于byte c = (byte)--a;
        System.out.println(b);//2
        System.out.println(c);//1
    }
}

运行结果:

image.png

(二)赋值运算符

1.分类:
=         等于号
+=        加等于
-=        减等于
*=        乘等于
/=        除等于
%=        取模等

(1)基本赋值运算符:
就是一个等号=,代表将右侧的数据交给左侧的变量。例:int a = 30;
代码:
(2)复合赋值运算符:

+=      a+=3      相当于      a = a+3
-=      a-=3      相当于      a = a-3
*=      a*=3      相当于      a = a*3
/=      a/=3      相当于      a = a/3
%=      a%=3      相当于      a = a%3

代码:

public class Operator{
    public static void main(String[] args){
        int i = 5;
        i+=5;//计算方式 i=i+5 变量i先加5,再赋值变量i
        System.out.println(i); //10
    }
}

运行结果:

image.png
2.注意事项:
  • 复合赋值运算符其中隐含了一个强制类型转换。
    代码:
public class Operator{
    public static void main(String[] args){
        byte num = 30;
        num += 5;//相当于num = (byte)(num+5);
        System.out.println(num);
    }
}

运行结果:

image.png

(三)比较运算符

1.分类:
==           比较符号两边数据是否相等,相等结果是true。
<            比较符号左边的数据是否小于右边的数据,如果小于结果是true。
>            比较符号左边的数据是否大于右边的数据,如果大于结果是true。
<=           比较符号左边的数据是否小于或者等于右边的数据,如果小于结果是true。
>=           比较符号左边的数据是否大于或者等于右边的数据,如果小于结果是true。
!=          不等于符号 ,如果符号两边的数据不相等,结果是true
2.注意事项:
  • 比较运算符的结果一定是一个boolean值,成立就是true,不成立就是false
  • 如果进行多次判断,不能连着写。
    数学当中的写法,例如:1< x <3,程序当中【不允许】这种写法。

代码:

public class Operator{
    public static void main(String[] args){
        System.out.println(1==1);//true
        System.out.println(1<2);//true
        System.out.println(3>4);//false
        System.out.println(3<=4);//true
        System.out.println(3>=4);//false
        System.out.println(3!=4);//true
        // System.out.println(1 < x < 3);//错误写法!编译报错!不能连着写。
    }
}

运行结果:

image.png

(四)逻辑运算符

1.分类:
&& 短路与              1.两边都是true,结果是true
                      2. 一边是false,结果是false
                      短路特点:符号左边是false,右边不再运算

|| 短路或             1. 两边都是false,结果是false
                     2. 一边是true,结果是true
                     短路特点: 符号左边是true,右边不再运算

! 取反                1. ! true 结果是false
                     2. ! false结果是true
2.注意事项:

(1)逻辑运算符只能用于boolean值。
(2)与、或需要左右各自有一个boolean值,但是取反只要有唯一的一个boolean值即可。
(3)与、或两种运算符,如果有多个条件,可以连续写。
两个条件:条件A&&条件B
多个条件:条件A&&条件B&&条件C

Tips:对于1<x<3的情况,应该拆成两个部分,然后使用与运算符连接起来:1<x && x<3

代码`:

public class Operator{
    public static void main(String[] args) {
        boolean a = true;
        int x = 2;
        System.out.println(true && true);//true
        System.out.println(true && false);//false
        System.out.println(false && !a);//false,右边不计算
        System.out.println(false || false);//false
        System.out.println(false || true);//true
        System.out.println(true || !a);//true,右边不计算
        System.out.println(!false);//true
        System.out.println("a="+a);
        // System.out.println(1 < x < 3);//错误写法!编译报错!不能连着写。
        System.out.println("1< x <3的结果为:" + (1 < x && x < 3));//应该改成这样
    }
}

运行结果:

image.png

(五)位运算符

1.分类:
&    按位与      a&b      a和b每一位进行"与"操作的结果"
|    按位或      a|b      a和b每一位进行"或"操作的结果"
~    取反        ~a       a每一位进行"非"操作的结果"
^    按位异或    a^b      a和b每一位进行"异或"操作的结果"
<<   左移        a<<b     将a左移b位,右边空位用0填充
<<   右移        a>>b     将a右移b位,丢弃被移出位,左边做高位用0或1填充
>>>  无符号右移  a>>>b    将a右移b位,丢弃被移出位,左边做高位用0填充
2.说明:

位运算符本质都是针对二进制数0和1进行运算的,在使用位运算符时,都会先将操作数转换成二进制数的形式进行位运算,然后将得到的结果再转换成想要的进制数。其中,1表示true,0表示false。

代码:

public class Operator{
    public static void main(String[] args){
        int a = 10;  // 0000 0000 0000 0000 0000 0000 0000 1010
        int b = 20;  // 0000 0000 0000 0000 0000 0000 0001 0100
        int c = -10; // 1111 1111 1111 1111 1111 1111 1111 0110
        System.out.println("a=" + a + ",b=" + b + ",c=" + c);
        
        // a & b      0000 0000 0000 0000 0000 0000 0000 1010(10)
                   // 0000 0000 0000 0000 0000 0000 0001 0100(20)
                   // ------------------------------------------ &
                   // 0000 0000 0000 0000 0000 0000 0000 0000(0)
        System.out.println("a&b=" + (a & b));
        
        // a | b      0000 0000 0000 0000 0000 0000 0000 1010(10)
                   // 0000 0000 0000 0000 0000 0000 0001 0100(20)
                   // ------------------------------------------ |
                   // 0000 0000 0000 0000 0000 0000 0001 1110(30)
        System.out.println("a|b=" + (a | b));
        
        // ~a         0000 0000 0000 0000 0000 0000 0000 1010(10)
                   // ------------------------------------------ ~
                   // 1111 1111 1111 1111 1111 1111 1111 0101(-11)
        System.out.println("~a=" + (~a));
        
        // a ^ b      0000 0000 0000 0000 0000 0000 0000 1010(10)
                   // 0000 0000 0000 0000 0000 0000 0001 0100(20)
                   // ------------------------------------------ ^
                   // 0000 0000 0000 0000 0000 0000 0001 1110(30)
        System.out.println("a^b=" + (a ^ b));
        
        // a << 1     0000 0000 0000 0000 0000 0000 0000 1010(10)
                   // ------------------------------------------ <<1
                   // 0000 0000 0000 0000 0000 0000 0001 0100(20)
        System.out.println("a<<1=" + (a << 1));
        
        // a >> 1     0000 0000 0000 0000 0000 0000 0000 1010(10)
                   // ------------------------------------------ >>1
                   // 0000 0000 0000 0000 0000 0000 0000 0101(5)
        System.out.println("a>>1=" + (a >> 1));
        
        // c >> 1     1111 1111 1111 1111 1111 1111 1111 0110(-10)
                   // ------------------------------------------ >>1
                   // 1111 1111 1111 1111 1111 1111 1111 1011(-5)
        System.out.println("c>>1=" + (c >> 1));
        
        // a >>> 1    0000 0000 0000 0000 0000 0000 0000 1010(10)
                   // ------------------------------------------ >>>1
                   // 0000 0000 0000 0000 0000 0000 0000 0101(5)
        System.out.println("a>>>1=" + (a >>> 1));
        
        // c >>> 1    1111 1111 1111 1111 1111 1111 1111 0110(-10)
                   // ------------------------------------------- >>>1
                   // 0111 1111 1111 1111 1111 1111 1111 1011(2147483643)
        System.out.println("c>>>1=" + (c >>> 1));
    }
}

运行结果:

image.png

(六)条件运算符(三元运算符)

1.格式:

数据类型 变量名 = 布尔类型表达式?结果1:结果2

2.流程:

(1)首先判断条件是否成立:
(2)如果成立为true,那么将表达式A的值赋值给左侧的变量;
(3)如果不成立为false,那么将表达式B的值赋值给左侧的变量;

3.注意事项:
  • 必须同时保证表达式A和表达式B都符合左侧数据类型的要求。
  • 三元运算符的结果必须被使用。
    代码:
public class Operator{
    public static void main(String[] args){
        int a = 10;
        int b = 20;
        double c = 2.5;
        //数据类型 变量名称 = 条件判断 ? 表达式A : 表达式B;
        //判断a > b是否成立,如果成立将a的值赋值给max;如果不成立将b的值赋值给max
        int max = a > b ? a : b;
        System.out.println("最大值:" + max);
        // int result = a > c ? a : c;//错误写法,必须同时保证表达式A和表达式B都符合左侧数据类型的要求
        // a > b ? a : b;//错误写法,三元运算符的结果必须被使用
    }
}

运行结果:

image.png

(七)运算符的优先级

运算符的优先级

口诀:括号级别最高,逗号级别最低,单目 > 算术 > 位移 > 关系 > 逻辑 > 三目 > 赋值。

三.方法

(一) 概述

我们在学习运算符的时候,都为每个运算符单独的创建一个新的类和main方法,我们会发现这样编写代码非常的繁琐,而且重复的代码过多。能否避免这些重复的代码呢,就需要使用方法来实现。

1.什么是方法?
  • 方法:就是将一个功能抽取出来,把代码单独定义在一个大括号内,形成一个单独的功能。当我们需要这个功能的时候,就可以去调用。这样即实现了代码的复用性,也解决了代码冗余的现象。

(二) 方法的定义

修饰符 返回值类型 方法名 (参数列表){
  方法体
  return;
}

Tips:
方法名称的命名规则和变量一样,使用小驼峰。
方法体:也就是大括号当中可以包含任意条语句。

代码:

public static void methodName() {
  System.out.println("这是一个方法");
}

(三) 方法的调用

1.为什么要调用

方法在定义完毕后,方法不会自己运行,必须被调用才能执行,我们可以在主方法main中来调用我们自己定义好的方法。在主方法中,直接写要调用的方法名字就可以调用了。

2.调用方法的流程图解
image.png

代码:

public class Method{
    public static void main(String[] args) {
        //调用定义的方法method
        method();
    }
    
    //定义方法,被main方法调用
    public static void method() {
        System.out.println("这是自己定义的方法,需要被main调用运行-_-");
    }
}

运行结果:

image.png
3.调用方法的三种形式
  • 直接调用:直接写方法名调用
  • 赋值调用:调用方法,在方法前面定义变量,接收方法返回值
  • 输出语句调用:在输出语句中调用方法System.out.println(方法名()) 。

代码:

public class Method {
    public static void main(String[] args) {
        // 单独调用
        System.out.print("单独调用:");
        sum(10, 20);
        System.out.println("===========");

        // 打印调用
        System.out.print("打印调用:");
        System.out.println("变量的值:" + sum(10, 20));
        System.out.println("===========");

        // 赋值调用
        System.out.print("赋值调用:");
        int number = sum(15, 25);
        System.out.println("变量的值:" + number);
    }

    public static int sum(int a, int b) {
        System.out.println("方法执行啦!");
        int result = a + b;
        return result;
    }
}

运行结果:

image.png

(四) 方法重载

1.什么是方法重载

方法重载(OverLoad):指在同一个类中,多个方法的名称一样,但是参数列表不一样(只要它们的参数列表不同即可,与修饰符和返回值类型无关)。

  • 参数列表:个数不同,数据类型不同,顺序不同。
  • 重载方法调用:JVM通过方法的参数列表,调用不同的方法。

代码:

public class MethodOverLoad {
    public static void main(String[] args) {
        System.out.println(sum(1, 2));
        System.out.println(sum(1, 2, 3));
        System.out.println(sum(1, 2, 3, 4));
        System.out.println(sum(1, 2, 3, 4, 5));
    }

    public static int sum(int a, int b) {
        System.out.println("可以传入两个参数的方法:");
        return a + b;
    }

    public static int sum(int a, int b, int c) {
        System.out.println("可以传入三个参数的方法:");
        return a + b + c;
    }

    public static int sum(int a, int b, int c, int d) {
        System.out.println("可以传入四个参数的方法:");
        return a + b + c + d;
    }

    public static int sum(int... params) {
        System.out.println("可以传入任意个参数的方法:");
        int sum = 0;
        for (int i : params) {
            sum += i;
        }
        return sum;
    }
}

运行结果:

image.png
2.使用方法重载注意事项

(1)方法重载与下列因素相关:

  • 参数个数不同
  • 参数类型不同
  • 参数的多类型顺序不同

(2)方法重载与下列因素无关:

  • 与参数的名称无关
  • 与方法的返回值类型无关

(五) 方法定义注意事项

  • 方法必须定义在类中
  • 方法的定义不能产生嵌套包含关系(方法不能定义在另一个方法的里面)
  • 不能在 return 后面写代码, return 意味着方法结束,所有后面的代码永远不会执行,属于无效代码。

代码:

public class Method {
    public static void main(String[] args){
    }
    //正确写法,类中,main方法外面可以定义方法
    public static void method(){}
}
// public class Method {
    // public static void main(String[] args){
        // //错误写法,一个方法不能定义在另一方法内部
        // public static void method(){}
    // }
// }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343