每日一点Java基础小知识 — day1
欢迎来到叮当猫学编程的Java基础小知识系列~在这里,你将会看到叮当猫每日关于Java的基础知识总结,期待大家的点赞关注喔
-
default和protected的区别是:
- 前者只要是外部包,就不允许访问
- 后者只要是子类就允许访问,即使子类位于外部包
- 总结:default拒绝一切包外访问;protected接受包外的子类访问
-
程序设计语言中,数组元素在内存中是一个接着一个线性存放的,通过第一个元素就能访问随后的元素,这样的数组称之为“真数组”;实现了真数组为Java语言健壮性的特点之一。
数组元素在内存中是一个接着一个线性存放的,通过第一个元素就能访问随后的元素,避免了数据覆盖的可能性,和数据类型覆盖并没有关系
-
虽然类中的private方法都隐式地指定为final,但是二者并不是等同的。private是访问权限修饰符,用于控制外界对类内部成员的访问,private方法只能在类的内部访问,而final方法可以在类外部访问
- final修饰类,表示类不可被继承
- final修饰变量,表示变量不可更改
- final修饰方法,表示方法不可被覆盖
private方法只可以在类的内部使用,在类外根本访问不到, 而final方法可以在类外访问,但是不可以重写该方法,就是说可以使用该方法的功能但是不可以改变其功能,这就是private方法和final方法的最大区别
-
AOP和OOP都是一套方法论,也可以说成设计模式、思维方式、理论规则等等
AOP不能替代OOP,OOP是obejct abstraction,而AOP是concern abstraction,前者主要是对对象的抽象,诸如抽象出某类业务对象的公用接口、报表业务对象的逻辑封装,更注重于某些共同对象共有行为的抽象,如报表模块中专门需要报表业务逻辑的封装,其他模块中需要其他的逻辑抽象 ,而AOP则是对分散在各个模块中的共同行为的抽象,即关注点抽象。一些系统级的问题或者思考起来总与业务无关又多处存在的功能,可使用AOP,如异常信息处理机制统一将自定义的异常信息写入响应流进而到前台展示、行为日志记录用户操作过的方法等,这些东西用OOP来做,就是一个良好的接口、各处调用,但有时候会发现太多模块调用的逻辑大都一致、并且与核心业务无大关系,可以独立开来,让处理核心业务的人专注于核心业务的处理,关注分离了,自然代码更独立、更易调试分析、更具好维护
核心业务还是要OOP来发挥作用,与AOP的侧重点不一样,前者有种纵向抽象的感觉,后者则是横向抽象的感觉, AOP只是OOP的补充,无替代关系
-
在方法内定义的变量在使用之前必须初始化,否则报错。
- 局部变量:方法定义中或者方法声明上
- 局部变量:在内存的栈中
- 局部变量:随方法的调用而存在,随着方法的调用完毕而消失
- 局部变量:没有默认值,必须定义,赋值,然后才能使用
-
boolean类型不可以转换成任何其他类型,因此它不能和整型变量比较
-
接口中的变量默认是 public static final 的,方法默认是 public abstract 的
-
关于抽象类
- 可以包含抽象方法
- 类中定义成员和方法不可以直接运算,可以写在代码块{}或者静态代码块中static{}中
- 用abstract修饰的抽象方法不能有方法体,如:
public abstract void method(int a);
,如果有方法体{},就不能作为抽象方法
-
Java类成员修饰符访问权限:public > protected > 同包(default) > private
-
java的String底层是char数组,它的length()返回数组大小,而unicode中一个汉字是可以用一个char表示的
一个汉字等于一个字符,字符 是char;一个汉字也等于二个字节,字节是byte
-
运行异常,可以通过java虚拟机来自行处理。非运行异常,我们应该捕获或者抛出
Java异常都继承自类Throwable,Throwable子类有Error和Exception,其中Exception又分为运行时异常和编译时异常。编译时异常是未雨绸缪性质的异常,是防范,需要显示处理。运行时异常是程序员问题造成,并不强制进行显示处理
-
所谓类的方法就是指类中用 static 修饰的方法(非static 为实例方法),比如main 方法,那么可以以main 方法为例,调用其他类方法时可直接调用,不能用this来调用
-
floor:意为地板,指向下取整,返回不大于它的最大整数
ceil : 意为天花板,指向上取整,返回不小于它的最小整数
round : 意为大约,表示“四舍五入”,而四舍五入是往大数方向入
Math.round(11.5)的结果为12,Math.round(-11.5)的结果为 -11而不是-12
-
forward 和 redirect是最常问的两个问题:
-
forward,服务器获取跳转页面内容传给用户,用户地址栏不变
-
redirect,是服务器向用户发送转向的地址,redirect后地址栏变成新的地址
redirect:请求重定向:客户端行为,本质上为2次请求,地址栏改变,前一次请求对象消失。举例:你去银行办事(forward.jsp),结果告诉你少带了东西,你得先去局办(index.html)临时身份证,这时你就会走出银行,自己前往局,地址栏变为index.html
forward:请求转发:服务器行为,地址栏不变。举例:你把钱包落在出租车上,你去警察局(forward.jsp)报案,警察局说钱包落在某某公司的出租车上(index.html),这时你不用亲自去找某某公司的出租车,警察局让出租车自己给你送来,你只要在警察局等就行。所以地址栏不变,依然为forward.jsp
-
-
静态数据成员可以在类体内进行初始化
-
公式:
-n = ~n + 1
=>~n = -n - 1
-
servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet
-
CGI(Common Gateway Interface),通用网关接口
通用网关接口,简称CGI,是一种根据请求信息动态产生回应内容的技术。通过CGI,Web 服务器可以将根据请求不同启动不同的外部程序,并将请求内容转发给该程序,在程序执行结束后,将执行结果作为回应返回给客户端。也就是说,对于每个请求,都要产生一个新的进程进行处理。因为每个进程都会占有很多服务器的资源和时间,这就导致服务器无法同时处理很多的并发请求。另外CGI程序都是与操作系统平台相关的,虽然在互联网爆发的初期,CGI为开发互联网应用做出了很大的贡献,但是随着技术的发展,开始逐渐衰落。
-
Servlet
Servlet最初是在1995年由James Gosling 提出的,因为使用该技术需要复杂的Web服务器支持,所以当时并没有得到重视,也就放弃了。后来随着Web应用复杂度的提升,并要求提供更高的并发处理能力,Servlet被重新捡起,并在Java平台上得到实现,现在提起Servlet,指的都是Java Servlet。Java Servlet要求必须运行在Web服务器当中,与Web服务器之间属于分工和互补关系。确切的说,在实际运行的时候Java Servlet与Web服务器会融为一体,如同一个程序一样运行在同一个Java虚拟机(JVM)当中。与CGI不同的是,Servlet对每个请求都是单独启动一个线程,而不是进程。这种处理方式大幅度地降低了系统里的进程数量,提高了系统的并发处理能力。另外因为Java Servlet是运行在虚拟机之上的,也就解决了跨平台问题。如果没有Servlet的出现,也就没有互联网的今天。
在Servlet出现之后,随着使用范围的扩大,人们发现了它的一个很大的一个弊端。那就是 为了能够输出HTML格式内容,需要编写大量重复代码,造成不必要的重复劳动。为了解决这个问题,基于Servlet技术产生了JavaServet Pages技术,也就是JSP。Servlet和JSP两者分工协作,Servlet侧重于解决运算和业务逻辑问题,JSP则侧重于解决展示问题。 Servlet与JSP一起为Web应用开发带来了巨大的贡献,后来出现的众多Java Web应用开发框架都是基于这两种技术的,更确切的说,都是基于Servlet技术的
-
-
Byte是byte的包装类型,初始化为null而不是0;在Java中,基本类型和
String = ""
方式创建的字符串的传递时传值,其他类型是传引用 -
servlet周期:
- init() --> 初始化
- service() --> 处理请求
- destory () --> 销毁(停止)
-
== 与 equals:
- ==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等; 如果作用于引用类型的变量,则比较的是所指向的对象的地址
- equals方法,注意:equals方法不能作用于基本数据类型的变量
- Object类中,equals方法是用来比较两个对象的引用是否相等,即是否指向同一个对象
- String类对equals方法进行了重写,用来比较指向的字符串对象所存储的字符串是否相等。其他的一些类诸如Double,Date,Integer等,都对equals方法进行了重写用来比较指向的对象所存储的内容是否相等
-
Java有5种方式来创建对象:
-
使用 new 关键字(最常用):
ObjectName obj = new ObjectName();
-
使用反射的Class类的newInstance()方法:
ObjectName obj = ObjectName.class.newInstance();
-
使用反射的Constructor类的newInstance()方法:
ObjectName obj = ObjectName.class.getConstructor.newInstance();
-
使用对象克隆clone()方法:
ObjectName obj = obj.clone();
-
使用反序列化(ObjectInputStream)的 readObject() 方法:
try ( ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_NAME)) ) { ObjectName obj = ois.readObject(); }
-
-
值传递与引用传递:
-
值传递(call by value)是将变量的一个副本传递到方法中,方法中如何操作该变量副本,都不会改变原变量的值
-
引用传递(call by reference)是将变量的内存地址传递给方法,方法操作变量时会找到保存在该地址的变量,对其进行操作。会对原变量造成影响
-
-
string与stringbuffer都是通过字符数组实现的
其中string的字符数组是final修饰的,所以字符数组不可以修改
stringbuffer的字符数组没有final修饰,所以字符数组可以修改
string与stringbuffer都是final修饰,只是限制他们所存储的引用地址不可修改
至于地址所指内容能不能修改,则需要看字符数组可不可以修改
-
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.***[i + (-IntegerCache.low)]; return new Integer(i); }
对于-128到127之间的数, Integer直接从数组中取,超过这个范围的数字(比如:2017…),这些都是new出来的对象,地址都不相同
-
代码优化可分为局部优化、 循环优化和全局优化:
- 局部优化指的是在只有一个入口、 一个出口的基本程序块上进行的优化
- 循环优化是对循环中的代码进行的优化,在一个程序运行时,相当多的一部分时间会花在循环上,因此,基于循环的优化非常重要。对循环中的代码段,可以进行代码外提、强度削弱和删除归纳变量等优化
- 全局优化是在整个程序范围内进行的优化。删除多余运算,使生成的目标代码减少而执行速度较快,也叫删除公共子表达式