java学习笔记之基础篇

java选择语句之switch
 
//switch可以用于等值判断
switch (e) //int ,或则可以自动转化成int 的类型,(byte char short)枚举jdk 7中可以防止字符串
{
case 6:
System.out.println();
break;
case 5:
System.out.println();
break;
case 4:
System.out.println();
break;
default:
System.out.println();
break;
}
 
//case后一般加break;防止出现case穿透现象;
 
java7新特性之switch
public class Test
{
public static void main(String[] args)
{
String a = "字符窜";
switch(a)
{
case "sfd":
System.out.println("1");
case "g":
System.out.println("2");
case "gaoqi":
System.out.println("3");
default:
System.out.println("4");
break;
}
}
}
 
 
 
java学习之循环语句
 
 
while循环有四个条件必须满足
1.初始化
2.比较判断
3.//循环体
4.迭代
while 先判断后执行
do while 先执行后判断
 
知道区别即可
 
for循环
 
 
在这里总结一下,java里面最基本的设计模式是自顶向下,结构化程序设计,当然这只是面向过程的,他还有面向对象的,就不再赘述
什么是结构化程序设计:
我想有以下三个最基本的条件,顺序,分支,循环
顺序比较简单,分支语句有if,if else,if else if else ,switch
循环有while,do while,for三个循环
 
java里跳转语句带标签的break和continue
 
标签的break和continue类似于其他语言里的go to
但是作为关键字保留
没有这个功能
在java中使用这个功能的地方是从内层循环跳到外层循环
int count = 0;
outer:for(int i = 101;i<101;i++)
{
for(int j=2;j<i/2;j++)
{
if(i%j=0)
continue outer;
}
System.out.println(i+" ");
}
对于break语句也是一样,break只能跳出当前循环,所以要跳出所有循环就要设置标签!
嗯嗯,这就是自己的总结笔记啊,虽然不少知识都忘了,但是,再学就记得更清了哈哈哈
 
 
 
 
java学习之方法及参数返回值
 
 
使用方法:方法是一段用来实现部分功能的片段
特点:复用代码很方便
注意事项:函数调用和定义应该分开
 
return语句结束方法运行,返回值
java中只有值传递,没有引用传递
 
设计原则:方法本意是功能块,就是实现某个功能语句的语句块集合。
我们设计方法的时候,一个方法,尽量只实现一个功能,保持原子性,这样利于我们后期扩张
 
 
java学习笔记-递归算法调用
 
什么是递归,递归是自己调用自己
递归要有结束的判断
否者就会无限地自己调用自己
public class TestRecursion
{
static int a = 0;
public static void test02()
{
a++;
System.out.println("111");
if(a<=10) //递归头
test02();
else //递归体
System.out.println(“over”);
}
}
递归头:什么时候不调用自身方法,如果没有头,将陷入死循环
递归体:什么时候需要调用自己
 
递归耗时耗空间
 
 
 
 
 
 
 
 
 
 
java学习笔记之package和生成API文档
 
API 应用程序编程接口
package:所有包
allclasses:所有类
包就是:为了解决类之间的重名问题
为了便于管理类:合适的类位于合适的包
包:域名倒着写即可,再加上模块名,并与内部管理类
jdk.lang 核心包:语言包
包含一些java语言的核心类,如String,System
 
 
如何生成自己的API文档,一定要写这样的注释:
@Author:作者
@version版本
@param参数
@return 返回值的含义
@throws 抛出异常描述
@deprecated废弃。建议用户不在使用改方法
 
使用特殊的注释
/**
*
测试递归算法
文档和代码放一起
然后点击项目,右键,export,点击java java doc
jdk里生成命令,目标文件夹
yes to all
打开index.html
即可看到项目下所有的类
类的说明
版本
方法介绍
 
java学习之键盘输入scanner类
 
在键盘输入中,要加包名
其次,在不通的方法中,同一个类实例化的方法名字可以用相同
public static void main(String[] args)
{
public static void test01()
{
Scanner s = new Scanner(System.in);
 
}
public static void test02()
{
Scanner s = new Scanner(System.in);
}
}
 
 
 
 
 
java学习-面向对象
 
一:面向对象与面向过程的区别
面向对象的特点是万物皆对象
类,三大基本特征:继承,封装,多态
面向对象其实是将一些方法聚集起来,封装成类
面向对象是组织代码,封装数据
c语言是以方法来组织代码
面向对象是以类来组织代码
将一些相关的行为和属性放在一起,便于管理
二:面向对象思考问题
首先,考虑事情里面有哪些对象
忽略细节,有了面向对象,依然要面向过程,底层
举例:如何造车:
1.面向对象:
车轮:
发动机:
车壳:
座椅:
最后组装在一起。
其实面向对象就是高层管理一样,面向过程就想工人一样;
三:类和对象的关系
对象:以类的方式组织代码,以对象的方式封装数据
面向对象编程:oop
面向对象思维:ooa,ood 面向对象分析,面向对象设计
类:是对象的抽象
先用类组织代码,
对象和类的关系:特殊到一般,具体到抽象
类:我们叫class
对象:object,instance(实例)
 
public class Student
{
//静态的数据
 
 
 
 
//动态的方法
}
java语言方法必须在类中
S1:建一个对象
创建一个新对象s2
以类组织代码,对象以类为模版
 
 
java学习笔记之面向对象执行过程内存分析
 
类中系统会自动帮你初始话:
引用数据类型接口,数组,类赋值null
基本数据类型赋值0,0.0
boolean false;
char \u 0000;
 
由主类作为入口,寻找这个类有没有被加载
如果没有被加载,通过类加载器,类文件加载在堆中class loader
加载后在方法去中就有了student信息
 
方法区:存放类的代码信息,static变量和常量池
 
栈中放置局部变量
 
new 出来的内容放在堆中
 
操作对象,就是操作地址
 
对象是通过引用类型操作的
 
基本数据类型可以直接赋值
 
每个方法都会对应一个栈帧
 
 
Student s1 = new Student();
Coumputer c = new Computer();
 
可以通过,s1.computer = c 引用
 
在方法区类,首先加载的是代码,其次是static,常量词
s1.computer 和c指向同一个值
 
 

java学习笔记-虚拟机内存管理和垃圾回收机制
 
垃圾回收机制
 
对象空间的分配:
使用new关键字创建对象即可
 
对象空间的释放:
将对象赋值null即可,垃圾回收器将负责回收所有“不可达”
对象的内存空间
 
程序员无权调用垃圾回收器
程序猿可以通过System.gc()通知GC运行,但是java规范并不能保证运行
finalize方法,是java提供给程序员用来释放对象或资源的方法
 
 

 
 
 
 
java学习笔记之面向对象执行过程内存分析
 
类中系统会自动帮你初始话:
引用数据类型接口,数组,类赋值null
基本数据类型赋值0,0.0
boolean false;
char \u 0000;
 
由主类作为入口,寻找这个类有没有被加载
如果没有被加载,通过类加载器,类文件加载在堆中class loader
加载后在方法去中就有了student信息
 
方法区:存放类的代码信息,static变量和常量池
 
栈中放置局部变量
 
new 出来的内容放在堆中
 
操作对象,就是操作地址
 
对象是通过引用类型操作的
 
基本数据类型可以直接赋值
 
每个方法都会对应一个栈帧
 
 
Student s1 = new Student();
Coumputer c = new Computer();
 
可以通过,s1.computer = c 引用
 
在方法区类,首先加载的是代码,其次是static,常量词
s1.computer 和c指向同一个值
 
 
 
 
 
 
 
 
 
 
 
 
 
java学习之构造器与重载
 
[修饰符]类名 (形参数列表)
 
定义有参的也不会加自动加构造方法;
如果自己不加构造器,编译器会自动加一个构造方法;
作用:构造类的方法,也经常用来初始属性;
可以将类的实例化作为一个形参数传入其中
 
构造方法也是方法
方法的重载是指一个类中可以定义有相同的名字,但参数不同的多个方法
自己起的类名尽量不和jdk中提供的类名相同
 
同一个类,同一个方法名
不同:参数列表不同(类型,个数,顺序)
顺序不同:
public static void main(int a,double b)
 
 
public static void main(double a,int b)
 
重载核心是调用时不构成歧义即可
 
 
java学习笔记之static变量和内存分析
 
static 声明的成员变量为静态变量或类变量
 
public class Student
{
String name;
int id;
static int ss;
 
public static void main(String[] args)
{
Student .ss = 323;
 
}
}
 
建立new,一个对象时static不会再被建立
对象以类为模版封装数据
在建立新的对象时,只会新建成员变量,static不再会被建立
因此,成员变量是由对象建立,而static变量一直在类中可以直接通过类来调用
 
在普通方法里面,可以调用非静态的东西
而在非静态方法里面,不可以调用普通的方法
 
类只能使用类的,对象既然能类的,也能使用对象的。
类中有
代码(方法—)
static变量
常量池
 
 
 
java学习之this隐式参数和内存分析
 
普通方法,里面会传递隐式参数
虚拟机默认传递this
指的是当前对象,值是当前对象的值
即通过this就可找到当前对象
通过this可以找到对象,区分对象
另外一个隐式参数是super
 
this不能用于static方法
第一,静态方法中没有对象
二,而static方法里没有this变量
 
 
在构造方法中this指向当前对象
this.name = name
public Student (String name,int id)
{
public Student(String name,int id)
{
this();
this.name = name;
this.id = id;
}
public Student()
{
System.out.println("");
}
 
}
 
java学习笔记之继承与方法重写
 
继承:
类是对对象的抽象,继承是对某一批类的抽象,从而实现对现实世界更好的建模
继承的目的是实现代码的复用性
在普通方法中可以通过this.run()来进行调用
 
子类继承父类,可以得到父类的全部属性和方法(除了父类的构造方法),继承无法继承构造器
java是c++-,c++中多继承可以有多个直接父类
java是单继承,java中不能有多个直接父类
 
 
多继承为了实现代码的父用性,却引入了复杂性
java中也有多继承,接口可以实现
类是单继承
 
定义一个类时间,如果没有调用exetends,默认继承Object类
 
继承可以重写,注意区分重写overload,重载
方法定义一样,但是实现内容不一样
继承是继承全部,但是调用时可以有所不同,可以灵活扩充
但是自己无法调用已经重写的内容,可以使用super调用。
 
java学习笔记之Object类用法以及toString和equals方法
 
如果想要查看jdk对象,鼠标放上去,按住ctrl键
Object obj = new Object();
System.out.println(obj.toString());
这个用来返回hash地址,不同的地址返回不同
重写toString方法时,可以重写,默认继承Object,toString在Object中
如何查看,一个类的父类,可以用ctrl + T键
hierachy层次结构
 
方法的重写:
在子类中可以更具需要对从基类中继承的方法进行重写
 
重写方法不能使用比父类方法更严格的权限
既可以继承父类的东西也可以进行扩充
用super.run调用父类方法
 
 
java学习笔记之继承
 
仅仅从代码复用角度来看,使用组合即可
可以随时组装
组合比继承更灵活一些,也能实现代码复用
“is-a”关系使用继承
哺乳动物是动物用继承
“has-a”关系使用组合
鸟有爪子
 
 
java学习笔记-final关键字
 
f inal的作用(最终的)
final int MAX_VALUE
修饰变量表示常量
在方法里面添加final,表示该方法不能被重写
final 也可以修饰类,表示该类不能被其他类继承
不能被重写,不能被继承
String , Math
 
java学习笔记-封装
 
我们程序的设计要求是高内聚,低耦合
高内聚就是类的内部数据操作细节自己完成,不允许外部干涉
低耦合:仅暴露少量的方法给外部使用
封装使用访问控制符实现:
同一个类:private,default,protected,public
同一个包:default,protected,public
不同包子类:protected,public
所有类:public
 
举例子:
***********************
public class Test01
{
private String str
private void print()
{
String s =str;//同一个类中可以调
System.out.println("test01");
}
}
 
public class Test02
{
public static void main(String[] args)
{
Test01 s1 = new Test01(); //同一个包不通类不可调用
 
}
}
***********************
 
public class Test01
{
default String str
default void print()
{
String s =str;//同一个类中可以调
System.out.println("test01");
}
}
 
public class Test03
{
public static void main(String[] args)
{
Test03 s1 = new Test03(); //default不同包不同类不可调用,只能限于一个包中
 
}
}
********************
 
***********************
包1
public class Test01
{
default String str
protected void print()
{
String s =str;//同一个类中可以调
System.out.println("test01");
}
}
包2
public class Test03 extendds Test01
{
public static void main(String[] args)
{
Test03 s1 = new Test03(); //不同包子类不调用
 
}
}
********************
 
 
 
protected:如果要不同包的子类,同一个类同一个包,不同包的字类
 
java学习笔记之多态
 
编译对应说,运行对应做
如果没有多态,用重载做
多态首先是又继承,方法要重写,父类的引用指向子类的对象
多态是一个基类,多个子类
public static void testAnimalVoice(Animal c)
{
c.voice();
 
}
cat c = new cat();
 
animal a = c;
 
**********
animal a = new cat();
**********
多态是方法的多态
public static void main(String[] args)
{
Animal a = new Cat();
Aniaml b = new Dog();
Animal c = new Tigger();
testAnimalVoice();
Cat a2 = (Cat)a;
a2.catMouse();
可以强制转换来调用多态没从父类继承的方法
 
}
 
 
 
如图所示,所有的构造方法,传递两个值一个super,一个this
java学习笔记之instanceof
 
instanceof是实例对象的意思
public static void testAnimalVoice(Animal c)
{
c.voice();
if(c instanceof Cat)
{
((Cat) c).catMouse();
 
}
}
 
 
多态内存分析
 
 
 
this指向最后本身的对象
 
多态内存深化分析(模拟servet中方法调用)
 
public class HttpServler
{
public void service()
{
System.out.println("");
doGet();
}
 
public void doGet()
{
System.out.println("");
}
 
}
 
public class MyServlet extends HttpServlet
{
public void doGet()
{
}
//重写doGet()
}
 
this是指向整个对象,而对象的外围的构造方法是外部对象的方法
所以如果子类和父类有相同的方法名,则应该是调用子类的方法
 
 
 
抽象类和抽象方法
 
抽象类是包含抽象方法的类,抽象方法只有方法的声明,没有方法体
只有定义,没有实现的方法
包含抽象方法的类,称为抽象类,一个抽象类实现另外一个抽象类
public abstract class Animal
{
public abstract void run();
}
 
定义抽象方法之后,必须实现我的抽象方法
注解jdk5.0后新加的
class Cat extends Animal
{
@override
public void run()
{
.........
}
}
 
抽象类中也可以添加普通方法,普通属性
通过抽象类,可以避免子类设计的随意性
定义抽象类的方法必须在子类中实现
在抽象类中也能够调用该类中的其他方法,应为多态
 
1有抽象方法的类只能定义为抽象类
2抽象类不能实例话,及不能用new来实例话抽象类
3抽象类可以包含属性,方法,构造方法,但是构造方法不能用来new实例
4抽象类只能用来继承,不能用来实例化对象,但是可以用来定义临时变量,再用子类来创建;
5抽象方法必须被子类实现,否则编译报错
 
抽象方法的意义在于:将方法的设计和方法的实现分离
 
 
接口
比抽象类还要抽象的类,就是接口
抽象类中可以定义普通的方法,但是接口中只能抽象方法
接口里包含常量和抽象方法
接口相当于规章制度,具体的实现通过其他东西
实现的话,用implements 实现
接口里常量定义时,都会有public statci final
 
public interface MyInterface
{
public static final String MAX_GREAD =" ";
public static final int MAX_SPEED =120;
public abstract void run();
}
 
接口的意义在于设计和实现的分离,它是最抽象的
 
 
现在我们要描述:
飞机 战斗机 无人机 导弹 子弹 篮球 石头的关系
public interfae Flyable
{
int max_speed = 1100;
int min_speed = 100;
void fly();
}
 
interface Attack()
{
attack();
}
class Man implements Flyable
{
public void fly()
{
System.out.println("跳,飞起来!");
}
}
 
class Stone implements Flyabe,Attack
{
public void fly()
{
System.out.println("被扔出去"!);
}
 
public void attack()
{
System.out.println("打"!);
}
}
 
为什么需要接口?接口和抽象类的区别:
接口是比抽象类还抽象的抽象类,可以更佳规范的对子类进行约束。全面钻也的实现了
具体现实和规范的分离。
接口就是规范,定义一组规则,体现了现实世界中“如果你是,则必须能。。。”
 
接口不能创建实例
 
接口能够多继承
public interface InterfaceA
{
void aaa();
}
public interface InterfaceB
{
void bbb();
}
interface InterfaceC extends InterfaceA,InterfaceB
{
void ccc();
}
 
 
class TestClass implements Interface
{
public void aaa(){}
public void bbb(){}
public void ccc(){}
}
 
回调的实现以及模版方法模式
 
public classs PaintFrame
{
public static void deawFrame(MyFrame f)
{
System.out.println(启动线程"");
System.out.println("增加循环");
System.out.println("查看消息栈");
 
//画窗口
f.paint(); //calback模版方法模式 ,hook
 
 
System.out.println("启动缓存,增加效率");
}
 
public statci void mian(String[] args)
{
drawFrame(new GameFrame02());
}
}
class MyFrame
{
public voi paint()
{
System.out.println("吧自己的窗口");
}
 
}
class GameFram01 extends MyFrame
{
public voi paint()
{
System.out.println("画窗口");
}
}
 
class GameFram01 extends MyFrame
{
public voi paint()
{
System.out.println("画窗口");
}
}
 
 
实现的地方和挂钩子的地方不一样,模版方法模式
public abstract class MyFrame
{
print();
}
也可以将MyFrame变成接IMyFrame
 
android中有很多类似的东西,只需要重写子类,对子类进行注册,自己一个定义对象,调用即可
 
内部类
 
1内部类提供了更好的封装。只能让外部类直接访问,不允许通一个包中的其他类直接方法
2内部类可以直接访问外部类的私有属性,但是外部类不能直接访问
 
非静态内部类:
非静态内部类必须既存在外部类对象里面。
public class Outer
{
public static void main(String[] args)
{
Face f = new Face();
Nose n = f.new Node();
或则
Face.Nose n = f.new Nose();
n.breath();
 
Face.Ear e = new Face.Ear();
e.listen();
 
}
}
class Face
{
int type;
static String color ="红润"
class Nose
{
String type;
void breath()
{
//访问外部sys(Face.this.type);
sys(type);
Sys("呼吸");
}
}
static class Ear
{
void listen()
{
sys(color);
Sys("我在听");
}
}
}
 
非静态内部类不能定义非静态方法
 
当一个静态内部类对象存在,并不一定存在对应的外部类
普通的成员内部类
静态内部类的外部类对象不一定存在,无法直接方法,静态内部类可以直接访问外部类的静态成员方法
 
 
 
java学习之数组内存原理
 
package xmlfile;
 
public class testarray
{
 
public static void main(String[] args)
{
/**
* 1.数组是相同数据类型(可以使任意数据类型)的有序集合
* 2.数据也是对象,数据中的元素相当于成员变量
* 3.数组长度是确定的
*/
 
Car[] a = new Car[10];
 
}
}
 
package xmlfile;
 
public class Car
{
String name;
public Car(String name)
{
this.name = name;
}
}
 
 
java学习之数组初始化
package xmlfile;
/**
* 数组的基本用法
* @author 刘红杨
*
*/
public class test02
{
public static void main(String[] args)
{
//声明
int[] a;
int b[];
//创建数组
a = new int[5];
b = new int[6];
//初始化
//默认初始化,数组的初始化都是默认初始化,相当于对象的成员变量,初始化方法默认的值规则和成员变量一样布尔false,char /u 00000,引用null
//动态初始化,大部分容器的底层都是用数组实现
a[0] =23;
//静态初始化
int c[] = {23,32,45};
Car[] cars = {
new Car("benchi"),
new Car("sfs"),
new Car("benc"),
new Car("sfs"),
};
 
}
 
}
 
String类的常用方法
package xmlfile;
/**
* 数组的基本用法
* @author 刘红杨
*
*/
public class test02
{
public static void main(String[] args)
{
String str = new String("abcd");
String str2 = new String("abcd");
 
//System.out.println(str.charAt(3));
 
 
System.out.println(str2.equals(str));
System.out.println(str2==str);
 
 
String str3 = "abc";
String str4 = "abc";
//指向常量池
System.out.println(str3.equals(str4));
System.out.println(str3==str4);
//equals直接指向数组value[]:'a','b','c','d'
//
 
}
 
}
str6="aaa,bbb,ccc"
charAt(int a):返回指定的值
indexOf(char ):返回索引下表
subString(0):从0开始截取到结尾
 
 
String[] strArray = str6.split(',');
遇到逗号就切割,str6返回三个字符串
 
replace("a","b")
 
 
 
equalsIgnoreCase(""):忽略大小写
lastIndexOf("");从后往前找
startsWith
endsWith
toLowerCase:转化为小写
toUpperCase:转化为大写
 
 
 
String gh ="a";
for(int i=0;i<1000;i++)
{
gh = gh + i;
}
System.out.println(gh);
一千零一个对象
 
String gh = new String("a");
 
for(int i=0;i<1000;i++)
{
gh = gh + i;
}
System.out.println(gh);
一千零二哥对象
 
StringBuilder和StringBuffer的使用
package xmlfile;
/**
*
* @author 刘红杨
* 测试可变字符序列。StringBuilder(线程不安全,效率高),StringBuffer(线程安全,效率低)
* string:不可变字符序列
*/
public class testarray {
 
public static void main(String[] args)
{
StringBuilder sb = new StringBuilder(); //字符数组长度为16
StringBuilder sb2 = new StringBuilder(32); //字符数组长度初始为32
StringBuilder sb3 = new StringBuilder("abcd"); //字符数组长度为20,
sb2.append("efg");
sb2.append(true);
 
sb2.append(true).append(321).append("谁便");
StringBuilder gh = new StringBuilder("a");
for(int i=0;i<1000;i++)
{
gh.append(i);
}
System.out.println(gh);
//会发生数组扩容由当前的长度*2+2;一直调用即可
}
}
 
一个是delete:用来删除
一个是reverse:用来反转
public class testarray {
 
public static void main(String[] args)
{
StringBuilder sb1= new StringBuilder("abcefghlmnopq");
sb1.delete(3,5);
System.out.println(sb1);//包含头不包含尾
StringBuilder sb2= new StringBuilder("abcefghlmnopq");
sb2.reverse(); //翻转字符
System.out.println(sb2);
}
}
 
问:string和stringbuilder的区别,浅一点儿可以说是string不可变字符序列。而stringbuilder是可变字符序列。在string中我们用一个字符数组来存储字符串,private final而在stringbuilder中没有这样定义,所以我门可以给stringbuilder扩容。可以反转字符。而且stringbuilder是不安全的,但是效率高和stringbuffer相比。
 
模拟ArrayList容器的底层实现
 
package xmlfile;
/**
* 模拟JDK中的ArrayList类
* @author 刘红杨
*
*/
public class myArrayList {
 
Object[] value;
int size;
public myArrayList()
{
this(10);//一个构造器调用另外一个构造器
}
 
public myArrayList(int size)
{
if(size<0)
{
try
{
throw new Exception();
}
catch(Exception e)
{
 
e.printStackTrace();
}
}
value = new Object[size];
}
public void add(Object obj)
{
value[size] = obj;
size++;
if(size>=value.length)
{
 
int newCapacity = value.length*2;
Object[] newList =new Object[newCapacity];
for(int i=0;i<value.length;i++)
{
newList[i] = value[i];
}
}
}
 
public int indexOf(Object obj)
{
if(obj==null)
{
return -1;
}
else
{
for(int i=0;i<=value.length-1;i++)
{
if(obj==value[i])
{
return i;
}
}
return -1;
}
 
}
public Object get(int index)
{
if(index<0||index>size-1)
{
try
{
throw new Exception();
}
catch(Exception e)
{
 
e.printStackTrace();
}
}
 
return value[index];
}
public static void main(String[] args)
{
myArrayList list = new myArrayList(2);
list.add("aaa");
list.add("vvv");
System.out.println(list.get(0));
}
 
 
}
多维数组
package xmlfile;
 
public class array {
public static void main(String[] args){
/**
*
* int[][] a={
* {1,2},
* {3,4},
* {5,6,7}
* }
*
*/
int[][] a = new int[3][];
a[0] = new int[1];
a[1] = new int[2];
a[2] = new int[3];
 
a[0][0] =1;
a[0][1] =2;
}
}
 
内存分析:
静态:
 
动态:
二维中第一维最初是引用,第二维才是存储的数组元素
 
 
 
数组的拷贝,排序,二分法,命令行参数,以及增强for循环
 
arraycopy数组拷贝,system类中
Arrays.sort(a):排序数组
Arrays.toString(a)
返回索引:Arrays.binarySearch(a,122);
填充:Arrays.file(a,2,4,100):将2到4的索引元素全换位100
 
 
 

猜你喜欢

转载自www.cnblogs.com/zhichun/p/11368469.html
今日推荐