在一个网站上面的一些基础知识,仅仅是一些比较泛泛而谈的一些东西,一些具体的知识仍然需要在项目实战中去拓展,当然啦,要是有时间看一看这些知识也是不错的,要是内容中有一些不同的看法的话,欢迎在评论中告知,我会尽快考量修改。
一起进步~~
面向对象
- 类就像一个模板那样,一个类中的每一个的属性都是对实例的抽象(比如每一位英雄都有各自的血量,攻速,护甲等)
- 然后可通过new方法实例化一个对象,这样就可以具体定义属性值
- 同时,还可以通过方法来定义一些自定义函数(比如英雄的击杀口号,回血,买装备等的方法定义)
变量
- 基本变量类型:整型×4,字符型1,浮点型2,布尔型*1(String不是基本变量类型但是类似常量)
- int(32位)byte(8位)float(32位)double(64位)boolean(1位)
- 类型转换:大换小直接换,小换大要强制
- 作用域
- 被声明在类下面(字段/属性/成员变量/Field)—>整个类
- 被声明再一个方法上(参数)—>方法内
- 被声明在方法内(局部变量)—>声明开始的位置到所处块结束位置
- 如果命名冲突,则就近原则取值
- final变量:当一个变量被final修饰的时候,只有一次被赋值的机会,赋值后便不可再修改
操作符
- 算数操作符:+ - × % 自增 自减
- 关系操作符:> < >= <= == !=
- 逻辑操作符:&(&&短路与) |(||短路或) !取反 ^异或
- 位操作符:&(按位与) ^(按位异或) ~(按位取反) <<(左移) >>(右移) |(按位或)
- 赋值操作符:=(赋值) +=(加等于)等
- 三元操作符: ?:(问号表达式)
- Scanner类:System.out.println("…")
控制流程
- if-else条件判断语句
- switch 条件分支语句
- while和do-while 循环语句
- for 循环语句(foreach语句)
- continue — 跳过当前循环继续下一次循环
- break 退出当前循环
数组
-
创建数组:int[] a = new int[5];这里是声明并创建了一个长度位5的整形数组。
-
初始化数组:
//写法一: 分配空间同时赋值 int[] a = new int[]{100,102,444,836,3236}; //写法二: 省略了new int[],效果一样 int[] b = {100,102,444,836,3236};
-
增强型for循环:遍历数组时更快捷
for(类型 循环变量名:循环数组)
//常规遍历 for (int i = 0; i < values.length; i++) { int each = values[i]; System.out.println(each); } //增强型for循环遍历 for (int each : values) { System.out.println(each); }
-
复制数组:可以用
arrayarraycopy
方法 -
二维数组:每一个元素都是一个一维数组
二维数组分配空间时要规定二维长度,元素中的一维数组的长度可用到的时候再分配,因此二维数组中每一个元素的一维数组的长度都可以不一样//分配空间并赋值 int a[][] = new int[][]{ {1,2,3}, {4,5}, {6,7,8,9} };; //分配空间 int a[][] = new int[2][];
-
数组Arrays:针对数组的工具类,可以进行排序,查找,复制填充等功能(copyOfRange,toString,sort,binarySearch,equals,fill)
equals和 ‘== ’ 的不同:’==’ 是一个操作符,用来判断两个变量或实例是不是指向同一个内存空间,equals是一个方法,用来判断两个变量或实例指向的内存空间的值是不是相同
类和对象
-
引用:一个变量类型是一个类类型而不是基本类型,该变量就叫做引用 —> Hero h = new Hero(); —> h是一个Hero类型,又叫做引用,=指h这个应用指向右侧创建的对象
-
继承:(extends关键词)子类继承父类后可引用父类成员变量,同时子类可在继承后继续添加成员变量
-
方法重载:指方法名不变,但方法的参数列表变了,可多个存在,使用时会根据参数来选择其中一个方法
- 可变参数列表(public void attack(Hero … heros){“可通过数组下标使用”})
-
构造方法:通过一个类创建一个对象的过程叫实例化,实例化是通过调用构造方法(构造器)实现的。
- 实例化一个对象时必然调用构造方法
- 名字和类名一样(区分大小写)
- 没有返回类型
- 如果不写,系统会默认提供一个
- 如果提供了一个有参的构造方法但是没有显式的提供一个无参的构造方法,那么默认的无参的构造方法就没有了
- 构造方法也可以重载
-
this关键字:this即代表当前对象
- 在一个构造方法中调用另一个构造方法
- 访问当前对象的属性(例如get,set方法中)
- 代表当前对象
-
传参:注意作用域
-
包:import引入,将类似的类放入一个包下
-
类属性(静态属性):类名.属性名调用;被static(静态)修饰,所有的对象都共享一个值,可变;与实例属性不同的是实力属性可不同的实例定义不同的值,而类属性是统一的
-
类方法(静态方法):类名.方法名调用;被static(静态)修饰;访问类方法不需要对象的存在,访问对象方法(实例方法)则必须建立在有一个对象的前提的基础上
-
属性初始化:
- 对象属性初始化:声明并初始化、构造方法中初始化、初始化块(语句块内包含多个初始化语句)
- 类属性初始化:声明并初始化,静态初始化块
-
单例模式:一个类在一个JVM中只有一个实例存在
- 饿汉式单例模式:通过私有化构造方法(private权限)使得该类无法在外部通过new进行实例化,然后准备一个类属性指向一个实例化对象,再通过类方法(public static)给外部调用该对象[因为类属性声明同时已经指向实例化对象,因此该类必有且仅有一个实例]
- 懒汉式单例模式:与饿汉式差不多,区别在与,懒汉式只有在调用类方法时才创建实例[类属性初始为null值,只有当调用时发现指向为null时才创建]
- 区别:饿汉式是立即加载的方式,无论是否会用到都会加载,如果在构造方法中写了性能消耗较大用时较久的代码,启动时消耗的时间会比较多;懒汉式是延迟加载的方式,只有在使用的时候才加载,并且有线程安全的考量,启动时会感觉较快,但是在第一次使用时会略慢
- 使用:根据业务需求分析是否有足够的启动和初始化时间,够就可以用饿汉式,不够可以使用懒汉式
- 单例模式三元素:构造方法私有化、静态属性指向实例、通过调用类方法返回静态属性
-
枚举enum类型:是一个特殊的类,主要用来定义固定的几个常量;枚举类型配合switch分支语句使用更方便;可通过增强型for循环遍历枚举
public enum Season{ SPRING,SUMMER,AUTUMN,WINTER }
-
接口与继承
- 创建:public interface name(){方法();}
- 调用:首先要类implements,其次在类内进行重写借口内方法(@Override)
- 对象转型:引用类型和对象类型不一致 —> 向上转型、向下转型(需要强制类型转换);转型需要有继承关系,没有继承关系的类型进行互相转换一定会失败;接口和实现类的互相转换;instanceof 可判断一个引用指向的对象
- 重写:子类继承父类对象方法后重复提供该方法,又称覆盖(Override),调用时会自动调用子类重写后的方法,而不是父类的防范,重写机制大大减少了开发时间,提高了开发效率
- 多态:父类引用指向子类对象调用的方法有重写 —> 编译看左,运行看右()
- 隐藏:子类覆盖父类的类方法(重写覆盖的是对象方法
- 一个指向子类对象的父类引用变量来调用父子同名的静态方法时,只会调用父类的静态方法
//father.java public class father { public static void print() { System.out.println("这是父类方法"); } } //child.java public class child extends father{ public static void print(){ System.out.println("这是子类方法"); } public static void main(String[] args){ father a = new child(); a.print(); } } //输出结果 这是父类方法
- super 关键字:显示调用父类构造(类)方法/对象方法
- Object类:声明一个类的时候默认是继承了Object类(所有类的父类);提供了toString(返回字符串表达式)、finalize(垃圾回收的时候调用)、equals(判断列两个引用指向的内容是否相等)、==(判断两个引用是否指向同一对象)、hashcode(返回一个对象的哈希值)、线程同步相关方法、getClass(返回一个对象的类对象)等fang方法,因此所有的类都能够直接调用这些方法
- final 关键字:
- 修饰类:该类不能被继承
- 修饰方法:该方法不能被重写
- 修饰基本类型变量:该变量只有一次赋值机会
- 修饰引用:该引用只有一次指向对象的机会,但是指向的对象可以修改
- 抽象类/抽象方法
- 使用abstract修饰
- 当一个类中有抽象方法时必须被声明为抽象类,抽象类中可以没有抽象方法,抽象方法所在的类肯定是抽象方法
- 抽象方法声明在抽象类中,没有实现体,是一个空方法;
- 抽象类和接口的区别:可以继承多个接口但是只能继承一个抽象类;接口中声明的属性只能是public,静态,final的;两者都可以有实体方法,接口中的实体方法叫做默认方法
11.内部类:
-
非静态内部类(只有一个外部类对象存在的时候才有意义–需要一个外部类实例作为基础,可以直接访问外部类的private属性)
-
静态内部类(static修饰,可以直接实例化,不可以访问外部类的实例属性和方法,能访问外部类的私有静态成员)
-
匿名类(声明一个类的同时实例化,更快速的实现)
-
本地类(有名字的匿名类)
-
内部类必须声明在成员的位置(与属性和方法平等的位置),匿名类在实例化语句中使用
-
匿名类中使用的外部局部变量必须修饰为final(jdk8后编译器会自动加上)
> 在匿名类中使用外部的局部变量damage 必须修饰为final
> 事实上的匿名类,会在匿名类里声明一个damage属性,并且使用构造方法初始化该属性的值
> 在attack中使用的damage,真正使用的是这个内部damage,而非外部damage
> 假设外部属性不需要声明为final
> 那么在attack中修改damage的值,就会被暗示为修改了外部变量damage的值
> 但是他们俩是不同的变量,是不可能修改外部变量damage的
> 所以为了避免产生误导,外部的damage必须声明为final,"看上去"就不能修改了 -
默认方法:JDK8之前接口只能提供抽象方法,JDK8后接口可以提供具体方法(默认方法)了;能够很好的扩展新的类并且做到不影响原来的类
当个性大于共性时,适合接口,如鸟和飞机,适合抽象出一个飞的接口
当共性大于个性时,适合抽象类,如老鹰和麻雀,适合抽象出一个鸟的父类
另外接口可以实现多重继承,这也是一个特点
两个接口方法相同时,实现两个接口的类可以用super调用/重写来调用所需方法
数字与字符串
-
所有的基本类型都有对应的类类型,成为封装类
- Number类
(Byte,Short,Intenger,Long,Float,Double)
- 基本类型转换成封装类型:
Intenger it = new Intenger(int i = 5);
- 封装类转换成基本类型:
int i = it.intValue();
- 自动装箱:
Intenger it = i;
通过’ = '自动把基本类型转换成类类型 - 自动拆箱:
int i = it;
通过’ = '自动转换称int类型 - 装箱后可调用封装类的方法(int 的最大值可用Intenger.MAX_VALUE)获取
- Number类
-
字符串转换
- 数字转换称字符串:
String str = String.valueOf(i);
ORIntenger it = i;String str = it.toString();
- 字符串转换成数字:
int i = Intenger.parseInt(str);
- 数字转换称字符串:
-
数学方法
Math.round(i)---四舍五入
Math.random()---0-1之间随机浮点数
Math.sqrt(i)---开方
Math.pow(x,y)---x的y次方
Math.PI--∏ Math.E--自然常数字
-
字符类型
- 封装类:
Character
Character.isLetter('a'); //判断是否为字母 Character.isDigit('a'); //判断是否为数字 Character.isWhitespace(' '); //是否是空白 Character.isUpperCase('a'); //是否是大写 Character.isLowerCase('a'); //是否是小写 Character.toUpperCase('a'); //转换为大写 Character.toLowerCase('A'); //转换为小写 String a = 'a'; //不能够直接把一个字符转换成字符串 String a2 = Character.toString('a'); //转换为字符串 String str = "abc123"; char[] cs = str.toCharArray(); //字符串转换成字符数组 String str2 = String.valueOf(cs);//字符数组转换成字符串
- 操作字符串
str.charAt(0)---获取指定位置字符 str.toCharArray()---获取对应的字符数组 str.subString(x,y)---截取从第x个开始到y的字符串(左闭右开) str.split(",")---根据,分隔符进行分隔 str.trim()---去掉首尾空格 str.toLowerCase/toUpperCase()---全部变成小写/大写 str.indexOf("i",a)---判断字符或子字符串出现的位置(从位置a开始出现第一次i的位置) str.contains("aaa")---检查是否包含字符串 str.replaceAll("x","y")/replaceFirst("x","y")---替换x为y/只替换第一个
- 封装类:
-
比较字符串
- 用
==
判断是否是同一个字符串对象 - 如果编译器发现创建的新的字符串值重复,则会直接使用已经创建的对象
str.startsWith("start")/str.endsWith("end")
是否以start开始/以end结束
-StringBuffer是可变长的字符串append
–追加,delete
–删除,insert
–插入,reverse
–反转- 机制:和String一样,内部维护一个字符数组,数组分配空间为19,留有冗余长度,若追加长度超过则会分配一个长度更长的新的数组,再将原来的数据复制到新的数组中去
- 用
日期
-
java.util.Date类
-
Java中0这个数字代表时间原点,对应日期是1970年1月1日8点整,美国1毫秒就+1
-
创建:
Date d1 = new Date();
-
getTime()
得到一个 long 型的正数,代表从时间原点开始经历的每一毫秒 -
System.currentTimeMillis()
和new Date().getTime()
是一样的 -
日期格式化:
- format — 日期转字符串
SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS" );//转换格式模式 Date d= new Date();//日期 String str = sdf.format(d);//转换成字符串
- parse — 字符串转日期(字符串的格式需与
yyyy/MM/dd HH:mm:ss
保持一致)
SimpleDateFormat sdf =new SimpleDateFormat("yyyy/MM/dd HH:mm:ss" );//转换格式模式 String str = "2016/1/5 12:12:12";//字符串 Date d = sdf.parse(str);//转换成日期
-
Calendar类(日历类)— 常用于进行翻日历,例如下个月的今天是多久
- 与Date进行转换
//采用单例模式获取日历对象Calendar.getInstance(); Calendar c = Calendar.getInstance(); //通过日历对象得到日期对象 Date d = c.getTime(); Date d2 = new Date(0); c.setTime(d2); //把这个日历,调成日期 : 1970.1.1 08:00:00
getinstance()
方法
- getInstance在单例模式(保证一个类仅有一个实例,并提供一个访问它的全局访问点)的类中常见,用来生成唯一的实例,getInstance往往是static的。
- 对象使用之前通过getinstance得到而不需要自己定义,用完之后不需要delete;
- new 一定要生成一个新对象,分配内存;getInstance() 则不一定要再次创建,它可以把一个已存在的引用给你使用,这在效能上优于new;
- new创建后只能当次使用,而getInstance()可以跨栈区域使用,或者远程跨区域使用。所以getInstance()通常是创建static静态实例方法的
- 翻日历(add方法、set方法)
public static void main(String[] args) { Calendar c = Calendar.getInstance(); Date now = c.getTime(); // 当前日期 System.out.println("当前日期:\t" + format(c.getTime())); // 下个月的今天 c.setTime(now); c.add(Calendar.MONTH, 1); System.out.println("下个月的今天:\t" +format(c.getTime())); // 去年的今天 c.setTime(now); c.add(Calendar.YEAR, -1); System.out.println("去年的今天:\t" +format(c.getTime())); // 上个月的第三天 c.setTime(now); c.add(Calendar.MONTH, -1); c.set(Calendar.DATE, 3); System.out.println("上个月的第三天:\t" +format(c.getTime())); } private static String format(Date time) { return sdf.format(time); }