赞
踩
Java标识符:由52个字母A-Z,a-z和数字、下划线、美元符号$组成,其中不能以数字开头。
**常用ASCII码值:**空格为32;数字0为48;“A”为65;“a”值为97。
**多态问题中,**无论向上或向下转型,都记住一句话就可以了。
**编译看左边,运行看右边。**意思编译时候,看左边有没有该方法,运行的时候结果看 new 的对象是谁,就调用的谁。
javac.exe是编译功能javaCompiler
java,exe是执行程序,用于执行编译好的.class文件
javadoc.exe用来制作java文档
jdb.exe是java的调试器
javaprof,exe是剖析工具
都是Throwable的子类:
1.Exception(异常):是程序本身可以处理的异常。
3.检查异常(编译器要求必须处置的异常) : 除了Error,RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常。这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。
4.非检查异常(编译器不要求处置的异常): 包括运行时异常(RuntimeException与其子类)和错误(Error)。
try的形式有三种:
1. try-catch
2. try-finally
3. try-catch-finally
//但catch和finally语句不能同时省略!
public Test() throws RepletException {
try { System.out.println("Test this Project!")
}catch (Exception e) {
throw new Exception(e.toString());
//Class.forName("com.mysql.jdbc.Driver"); //指定MySQL JDBC驱动程序 //oracle.jdbc.driver.OracleDriver //oracle驱动 //sun.jdbc.odbc.JdbcOdbcDriver//Access数据库 String url = "数据库连接地址"; String user = "用来连接数据库的用户名"; String pwd = "用来连接数据库的密码"; Class.forName("com.mysql.jdbc.Driver"); //加载jdbc驱动 Connection con=DriverManager.getConnection(url,user,password); //建立连接 Statement stmt=con.createStatement(); //创建语句执行者(stateMent用于执行不带参数的简单sql语句,PreparedStatement用于执行带参数的预编译sql语句能够预防sql注入(要传入sql语句),CallableStatement提供了一种标准形式的调用存储过程的方法) stmt.execute(“sql语句”); rs=stmt.executeQuery("sql查询语句"); //结果集 rs.close(); s.close(); con.close(); //关闭结果集对象Resultset,statement对象,connection对象 ... //各个步骤的异常处理
1.首先,需要明白类的加载顺序。(同一类型按从上到下执行)
(1) 父类静态域(包括静态初始化块,静态属性,静态方法,静态方法是最后执行的)
(2) 子类静态域(包括静态初始化块,静态属性,静态方法 ,静态方法是最后执行的)
(3) 父类非静态代码块( 包括非静态初始化块,非静态属性 )
(4) 父类构造函数
(5) 子类非静态代码块 ( 包括非静态初始化块,非静态属性 )
(6) 子类构造函数
其中:类中静态块按照声明顺序执行,并且(1)和(2)不需要调用new类实例的时候就执行了(意思就是在类加载到方法区的时候执行的)
2.其次,需要理解子类覆盖父类方法的问题,也就是方法重写实现多态问题。
Base b = new Sub();它为多态的一种表现形式,声明是Base,实现是Sub类, 理解为 b 编译时表现为Base类特性,运行时表现为Sub类特性。
当子类覆盖了父类的方法后,意思是父类的方法已经被重写,题中 父类初始化调用的方法为子类实现的方法,子类实现的方法中调用的baseName为子类中的私有属性。
由1.可知,此时只执行到步骤4.,子类非静态代码块和初始化步骤还没有到,子类中的baseName还没有被初始化。所以此时 baseName为空。所以为null。
(1)构造方法的方法名必须与类名相同。
(2)构造方法没有返回类型,也不能定义为void,在方法名前面不声明方法类型。
(3)构造方法的主要作用是完成对象的初始化工作,它能够把定义对象时的参数传给对象的域。
(4)一个类可以定义多个构造方法,如果在定义类时没有定义构造方法,则编译系统会自动插入一个无参数的默认构造器,这个构造器不执行任何代码。
(5)构造方法可以重载,以参数的个数,类型,顺序。
类方法:类可以直接调用的方法,即static修饰的静态方法
实例方法:通过实例调用的方法,即没有用static修饰的普通方法
区别:
实例变量的定义类似实例方法,没有用static修饰的变量,实例变量的创建与实例方法的创建相同,也是在类的对象创建时完成,所以在类方法中是不能引用实例变量的,因为这个时候实例变量还没有分配内存地址。
这是因为super和this都指向的是父类和本类的对象,而在类方法中调用的时候,这些指代的对象有可能都还没有创建。
类方法中不能直接调用实例方法
可间接调用,先生成对象。通过对象即可调用实例方法
类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段。其中准备、验证、解析3个部分统称为连接(Linking)。如图所示。
加载、验证、准备、初始化和卸载这5个阶段的顺序是确定的,类的加载过程必须按照这种顺序按部就班地开始,而解析阶段则不一定:它在某些情况下可以在初始化阶段之后再开始,这是为了支持Java语言的运行时绑定(也称为动态绑定或晚期绑定)。以下陈述的内容都已HotSpot为基准。
在加载阶段(可以参考java.lang.ClassLoader的loadClass()方法),虚拟机需要完成以下3件事情:
加载阶段和连接阶段(Linking)的部分内容(如一部分字节码文件格式验证动作)是交叉进行的,加载阶段尚未完成,连接阶段可能已经开始,但这些夹在加载阶段之中进行的动作,仍然属于连接阶段的内容,这两个阶段的开始时间仍然保持着固定的先后顺序。
验证是连接阶段的第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。
验证阶段大致会完成4个阶段的检验动作:
验证阶段是非常重要的,但不是必须的,它对程序运行期没有影响,如果所引用的类经过反复验证,那么可以考虑采用-Xverifynone参数来关闭大部分的类验证措施,以缩短虚拟机类加载的时间。
准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区中进行分配。这时候进行内存分配的仅包括类变量(被static修饰的变量),而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在堆中。其次,这里所说的初始值“通常情况”下是数据类型的零值,假设一个类变量的定义为:
1 | publicstaticintvalue=123; |
---|---|
那变量value在准备阶段过后的初始值为0而不是123.因为这时候尚未开始执行任何java方法,而把value赋值为123的putstatic指令是程序被编译后,存放于类构造器()方法之中,所以把value赋值为123的动作将在初始化阶段才会执行。
至于“特殊情况”是指:public static final int value=123,即当类字段的字段属性是ConstantValue时,会在准备阶段初始化为指定的值,所以标注为final之后,value的值在准备阶段初始化为123而非0.
解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符7类符号引用进行。
类初始化阶段是类加载过程的最后一步,到了初始化阶段,才真正开始执行类中定义的java程序代码。在准备极端,变量已经付过一次系统要求的初始值,而在初始化阶段,则根据程序猿通过程序制定的主管计划去初始化类变量和其他资源,或者说:初始化阶段是执行类构造器()方法的过程.
()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块static{}中的语句合并产生的,编译器收集的顺序是由语句在源文件中出现的顺序所决定的,静态语句块只能访问到定义在静态语句块之前的变量,定义在它之后的变量,在前面的静态语句块可以赋值,但是不能访问
普通类(外部类):只能用public、default(不写)、abstract、final修饰。
(成员)内部类:可理解为外部类的成员,所以修饰类成员的public、protected、default、private、static等关键字都能使用。
局部内部类:出现在方法里的类(类似局部变量),不能用上述关键词来修饰。
匿名内部类:给的是直接实现,类名都没有,没有修饰符,由于构造器的名字必须与类名相同,而匿名类没有类名,所以匿名类不能有构造器。
注意:外部类只能有一个Public。
Java语言提供了很多修饰符,大概分为两类:
注意:
内部类与成员变量地位一样,所以可以public、protected、default和private,同时还可以用static修饰,表示嵌套内部类,不用实例化外部类,即可调用。
1.静态内部类才可以声明静态方法
2.静态方法不可以使用非静态变量
3.抽象方法不可以有函数体
public(公共控制符),包外包内都可以调用该方法。
protected(保护访问控制符)指定该方法可以被它的类和子类进行访问。具体细节可参考:http://blog.csdn.net/dawn_after_dark/article/details/74453915
default(默认权限),指定该方法只对同包可见,对不同包(含不同包的子类)不可见。
private(私有控制符)指定此方法只能有自己类等方法访问,其他的类不能访问(包括子类),非常严格的控制。
final ,指定方法已完备,不能再进行继承扩充。
static,指定不需要实例化就可以激活的一个方法,即在内存中只有一份,通过类名即可调用。
synchronize,同步修饰符,在多个线程中,该修饰符用于在运行前,对它所属的方法加锁,以防止其他线程的访问,运行结束后解锁。
native,本地修饰符。指定此方法的方法体是用其他语言在程序外部编写的。
abstract ,抽象方法是一种没有任何实现的方法,该方法的的具体实现由子类提供。抽象方法不能被声明成 final 和 static(static方法不能被覆盖)。 任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。 如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。 抽象方法的声明以分号结尾,例如:public abstract sample();。
注意:静态方法中只能调用静态成员或者方法,不能调用非静态方法或者非静态成员(实例化后间接调用),而非静态方法既可以调用静态成员或者方法又可以调用其他的非静态成员或者方法。
final 和 static 经常一起使用来创建常量。
only final is permitted。
为什么不能赋予权限修饰符?
因为局部变量的生命周期为一个方法的调用期间,所以没必要为其设置权限访问字段,既然你都能访问到这个方法,所以就没必要再为其方法内变量赋予访问权限,因为该变量在方法调用期间已经被加载进了虚拟机栈,换句话说就是肯定能被当前线程访问到,所以设置没意义。
为什么不能用static修饰
我们都知道静态变量在方法之前先加载的,所以如果在方法内设置静态变量,可想而知,方法都没加载,你能加载成功方法内的静态变量?
接口修饰符只能用public、default和abstract。 (因为接口作用的域是包,所以不需要protected等修饰符来修饰,用public和default区分即可)
不能用final、static修饰。
接口默认修饰为abstract。
接口中的变量修饰符
public final static
接口中方法修饰符
only public & abstract are permitted 。
意思只能用 public abstract修饰,当然如果你什么都不写,默认就是public abstract。
注意:
在Java1.8中,接口**允许定义static 静态方法**了!所以也可以用static来修饰!
重载:重载是在同一个类中,有多个方法名相同,参数列表不同(参数个数不同,参数类型不同,多个参数类型不一致的顺序不同),与方法的返回值无关,与权限修饰符无关。
重写:在子类中,子类继承父类的方法,方法名,参数列表,放回去值都需要相同。
两同两小一大原则:
方法名相同,参数类型相同
子类返回类型小于等于父类方法返回类型,
子类抛出异常小于等于父类方法抛出异常,
子类访问权限大于等于父类方法访问权限。
**equals:**没有被重写时,和“==”一样,被重写后(String类中)比较的是两者的内容。
**"==":**比较的是两者对应的地址。
**1. **类与类之间的关系为继承,只能单继承,但可以多层继承。
2. 类与接口之间的关系为实现,既可以单实现,也可以多实现。
**3. **接口与接口之间的关系为继承,既可以单继承,也可以多继承。
**4. **抽象类可以有构造,只不过不能new。
**5. ** 接口中可以有变量,但是无论你怎么写,最后都是public static final的。
**6. **抽象类中可以有静态方法,接口中也可以有。
扩展:
1、接口中可以有非抽象的方法,比如default方法(Java 1.8)。
2、接口中可以有带方法体的方法。(Java 1.8)
3、接口中的方法默认是public的。
注意:super()和this()都只能位于构造器的第一行,而且不能同时使用,这是因为会造成初始化两次,this()用于调用重载的构造器,super()用于调用父类被子类重写的方法。如果父类中包含有参构造器,却没有无参构造器,则在子类构造器中一定要使用**“super(参数)”**指定调用父类的有参构造器,不然就会报错。
实现接口:
run方法线程执行体.start方法开启多线程
1.sleep()方法
在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”。不推荐使用。
sleep()使当前线程进入阻塞状态,在指定时间内不会执行。
2.wait()方法
在其他线程调用对象的notify或notifyAll方法前,导致当前线程等待。线程会释放掉它所占有的“锁标志”,从而使别的线程有机会抢占该锁。
当前线程必须拥有当前对象锁。如果当前线程不是此锁的拥有者,会抛出IllegalMonitorStateException异常。
唤醒当前对象锁的等待线程使用notify或notifyAll方法,也必须拥有相同的对象锁,否则也会抛出IllegalMonitorStateException异常。
wait()和notify()必须在synchronized函数或synchronized block中进行调用。如果在non-synchronized函数或non-synchronized block中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。
3.yield方法
暂停当前正在执行的线程对象。
yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。
yield()只能使同优先级或更高优先级的线程有执行的机会。
4.join方法
join()等待该线程终止。
等待调用join方法的线程结束,再继续执行。如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,导致结果不可预测
**首先:**创建并启动线程的过程为:定义线程—》实例化线程—》启动线程。
一 、定义线程:
1、继承java.lang.Thread类。 重载run方法。
2、实现java.lang.Runnable接口。实现run方法。
二、实例化线程:
1、如果是扩展java.lang.Thread类的线程,则直接new即可。
2、如果是实现了java.lang.Runnable接口的类,则用Thread的构造方法:
Thread(Runnable target)
Thread(Runnable target, String name)
Thread(ThreadGroup group, Runnable target)
Thread(ThreadGroup group, Runnable target, String name)
Thread(ThreadGroup group, Runnable target, String name, long stackSize)
三、启动线程: 在线程的Thread对象上调用start()方法,而不是run()或者别的方法。
ThreadLocal的作用是使数据的独立
助记:“是你 有你 一切拜托你”
“is a” “has a” “uses a”
public class Hashtable extends Dictionary implements Map public class HashMap extends AbstractMap implements Map
Hashtable 中的方法是同步的(synchronized),而HashMap中的方法在缺省情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。
Hashtable中,key和value都不允许出现null值。
在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示 HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。
两个遍历方式的内部实现上不同。
Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。
哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。
Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。
**switch**支持 int及以下(char, short, byte),String(jdk1.7), Enum(枚举)
**喂!SHE! **
喂是指 vector,S是指 stack, H是指 hashtable,E是指:Eenumeration
修饰引用变量,引用不能变,内容可以变;
修饰基本数据类型的变量,内容不能变
class Vehicle {
int passengers;
int fuelcap;
int mpg;
}
有了这个模板,就可以用它来创建对象:
Vehicle veh1 = new Vehicle();
通常把这条语句的动作称之为创建一个对象,其实,它包含了四个动作。
在if语句中,&&当第一个条件不成之后,后面的条件都不执行了,而**&则还是继续执行,直到整个条件语句执行完为止**
public class Test { public static void main(String[] args) { int x = 0; int y = 0; int k = 0; for (int z = 0; z < 5; z++) { if ((++x > 2) && (++y > 2) && (k++ > 2)) { x++; ++y; k++; } } System.out.println(x + ”” +y + ”” +k); } } //答案为 531
语法和&、&&基本一样,
当使用|时,无论正确与否,都会执行后面的运算,
当使用||时,第一个就达到目标后,后面的就不会去执行
String(大姐,出生于JDK1.0时代) 不可变字符序列 <StringBuffer(二姐,出生于JDK1.0时代) 线程安全的可变字符序列 <StringBuilder(小妹,出生于JDK1.5时代) 非线程安全的可变字符序列。
这两者的方法没有很大区别。但在线程安全性方面,StringBuffer允许多线程进行字符操作。 这是因为在源代码中StringBuffer的很多方法都被关键字 synchronized 修饰了,而StringBuilder没有。 StringBuilder的效率比StringBuffer稍高,如果不考虑线程安全,StringBuilder应该是首选。
举个例子:
String str = “aa”; str = “aa”+“bb”; 此时str的值为"aabb",但是**“aabb"不是在开始的字符串"aa"后面直接连接的"bb”,而是又新生成了字符串"aabb"**,字符串"aa"一旦被初始化,那么它的值不可能再改变了。
StringBuffer strb = StringBuffer("aa");
strb.append("bb");
此时的strb的值也为"aabb",但是"aabb"是直接在开始的字符串"aa"后面连接的“bb”,并没有生成新的字符串。
序列化保存的是对象的状态,不能对static变量和transient修饰的变量序列化。
序列化:将数据结构转换称为二进制数据流或者文本流的过程。序列化后的数据方便在网络上传输和在硬盘上存储。****
反序列化:与序列化相反,是将二进制数据流或者文本流转换称为易于处理和阅读的数据结构的过程。
图中Hashtable也该继承的是Dictionary类;
线程安全的ArrayList。在内存中占用连续的空间。初始时有一个初始大小,当数据条数大于这个初始大小后会重写分配一个更大的连续空间。如果Vector定义为保存Object则可以存放任意类型。
**JRE:**Java Runtime Environment,也就是JVM的运行平台,联系平时用的虚拟机,大概可以理解成JRE=虚拟机平台+虚拟机本体(JVM)
**JDK:**Java Develop Kit,Java的开发工具包,JDK本体也是Java程序,因此运行依赖于JRE,由于需要保持JDK的独立性与完整性,JDK的安装目录下通常也附有JRE。
Java基本类型占用的字节数:
1字节: byte , boolean(1位)
2字节: short , char
4字节: int , float
8字节: long , double
(1字节=8位)
包的作用
1、基本型和基本型封装型进行“==”运算符的比较,基本型封装型将会自动拆箱变为基本型后再进行比较,因此Integer(0)会自动拆箱为int类型再进行比较,显然返回true;
2、两个Integer类型进行“==”比较,如果其值在-128至127,那么返回true,否则返回false, 这跟Integer.valueOf()的缓冲对象有关,这里不进行赘述。
3、两个封装类型的对象进行“==”比较**,对应的内存地址不同,返回false**
4、两个基本型的封装型进行equals()比较**,首先equals()会比较类型,如果类型相同,则继续比较值,如果值也相同,返回true
5、基本型封装类型调用equals(),但是参数是基本类型,这时候,先会进行自动装箱,基本型转换为其封装类型,再进行3中的比较。
int a=257;
Integer b=257;
Integer c=257;
Integer b2=57;
Integer c2=57;
System.out.println(a==b);
//System.out.println(a.equals(b)); 编译出错,基本型不能调用equals()
System.out.println(b.equals(257.0));
System.out.println(b==c);
System.out.println(b2==c2);
上面的代码的结果因此为 True、False、False、True
1.new时初始化 ;
2.静态工厂 newInstance;
3.反射Class.forName();
4.clone方式;
5.反序列化;
在方法中,修改一个基础类型的参数永远 不会影响原始参数值。
在方法中,改变一个对象参数的引用永远 不会影响到原始引用。然而,它会在堆中创建了一个全新的对象。(译者注:指的是包装类和immutable对象)
在方法中,修改一个对象的属性 会影响原始对象参数。
在方法中,修改集合和Maps 会影响原始集合参数。
**参考文档:**https://blog.csdn.net/scholar_man/article/details/80900212
[外链图片转存失败(img-GlQeTj5C-1568202383672)(C:\Users\Leisure\AppData\Roaming\Typora\typora-user-images\1567823749780.png)]
数据类型的转换,分为自动转换和强制转换。自动转换是程序在执行过程中 “ 悄然 ” 进行的转换,不需要用户提前声明,一般是从位数低的类型向位数高的类型转换;强制类型转换则必须在代码中声明,转换顺序不受限制。
自动转换按从低到高的顺序转换。不同类型数据间的优先关系如下:
低 ---------------------------------------------> 高
byte,short,char-> int -> long -> float -> double
运算中,不同类型的数据先转化为同一类型,然后进行运算,转换规则如下:
操作数 1 类型 | 操作数 2 类型 | 转换后的类型 |
---|---|---|
byte 、 short 、 char | int | int |
byte 、 short 、 char 、 int | long | long |
byte 、 short 、 char 、 int 、 long | float | float |
byte 、 short 、 char 、 int 、 long 、 float | double | double |
强制转换的格式是在需要转型的数据前加上 “( )” ,然后在括号内加入需要转化的数据类型。有的数据经过转型运算后,精度会丢失,而有的会更加精确
ServerSocket(int port) 是服务端绑定port端口,调accept()监听等待客户端连接,它返回一个连接队列中的一个socket。
Socket(InetAddress address , int port)是创建客户端连接主机的socket流,其中InetAddress是用来记录主机的类,port指定端口。
参考文档:http://www.cnblogs.com/rond/p/3565113.html
JSP内置对象有:
客户端的请求信息被封装在request对象中,通过它才能了解到客户的需求,然后做出响应。它是HttpServletRequest类的实例。
response对象包含了响应客户请求的有关信息,但在JSP中很少直接用到它。它是HttpServletResponse类的实例。
session对象指的是客户端与服务器的一次会话,从客户连到服务器的一个WebApplication开始,直到客户端与服务器断开连接为止。它是HttpSession类的实例.
out对象是JspWriter类的实例,是向客户端输出内容常用的对象
page对象就是指向当前JSP页面本身,有点象类中的this指针,它是java.lang.Object类的实例
application对象实现了用户间数据的共享,可存放全局变量。它开始于服务器的启动,直到服务器的关闭,在此期间,此对象将一直存在;这样在用户的前后连接或不同用户之间的连接中,可以对此对象的同一属性进行操作;在任何地方对此对象属性的操作,都将影响到其他用户对此的访问。服务器的启动和关闭决定了application对象的生命。它是ServletContext类的实例。
exception对象是一个例外对象,当一个页面在运行过程中发生了例外,就产生这个对象。如果一个JSP页面要应用此对象,就必须把isErrorPage设为true,否则无法编译。他实际上是java.lang.Throwable的对象
pageContext对象提供了对JSP页面内所有的对象及名字空间的访问,也就是说他可以访问到本页所在的SESSION,也可以取本页面所在的application的某一属性值,他相当于页面中所有功能的集大成者,它的本 类名也叫pageContext。
config对象是在一个Servlet初始化时,JSP引擎向它传递信息用的,此信息包括Servlet初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个ServletContext对象)
按照流是否直接与特定的地方(如磁盘、内存、设备等)相连,分为节点流和处理流两类。
JAVA常用的节点流:
常用处理流(关闭处理流使用关闭里面的节点流)
求小于参数的最大整数。返回double类型-----n. 地板,地面
例如:Math.floor(-4.2) = -5.0
-----------------------------------------------------------
求大于参数的最小整数。返回double类型-----vt. 装天花板;
例如:Math.ceil(5.6) = 6.0
-----------------------------------------------------------
它表示“四舍五入”,算法为Math.floor(x+0.5),即将原来的数字加上0.5后再向下取整,返回int类型
例如:Math.round(11.5)的结果为12,Math.round(-11.5)的结果为-11
先进行模运算,再取除数的符号。
结构型模式是描述如何将类对象结合在一起,形成一个更大的结构,结构模式描述两种不同的东西:类与类的实例。故可以分为类结构模式和对象结构模式。
在GoF设计模式中,结构型模式有:
适配器模式是将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
两个成熟的类需要通信,但是接口不同,由于开闭原则,我们不能去修改这两个类的接口,所以就需要一个适配器来完成衔接过程。
桥接模式将抽象部分与它的实现部分分离,是它们都可以独立地变化。它很好的支持了开闭原则和组合锯和复用原则。实现系统可能有多角度分类,每一种分类都有可能变化,那么就把这些多角度分离出来让他们独立变化,减少他们之间的耦合。
组合模式将对象组合成树形结构以表示部分-整体的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
装饰模式动态地给一个对象添加一些额外的职责,就增加功能来说,它比生成子类更灵活。也可以这样说,装饰模式把复杂类中的核心职责和装饰功能区分开了,这样既简化了复杂类,有去除了相关类中重复的装饰逻辑。 装饰模式没有通过继承原有类来扩展功能,但却达到了一样的目的,而且比继承更加灵活,所以可以说装饰模式是继承关系的一种替代方案。
外观模式为子系统中的一组接口提供了同意的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
外观模式中,客户对各个具体的子系统是不了解的,所以对这些子系统进行了封装,对外只提供了用户所明白的单一而简单的接口,用户直接使用这个接口就可以完成操作,而不用去理睬具体的过程,而且子系统的变化不会影响到用户,这样就做到了信息隐蔽。
享元模式为运用共享技术有效的支持大量细粒度的对象。因为它可以通过共享大幅度地减少单个实例的数目,避免了大量非常相似类的开销。.
享元模式是一个类别的多个对象共享这个类别的一个对象,而不是各自再实例化各自的对象。这样就达到了节省内存的目的。
为其他对象提供一种代理,并由代理对象控制对原对象的引用,以间接控制对原对象的访问。
C++中的概念
虚函数:Java中的普通方法;
纯虚函数:java中的抽象方法。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。