1、查看已安装jdk文件路径
CMD输入java -verbose。
2、java学习提升路线
java学习视屏地址:
各阶段所需要看的书:
《Java编程思想》,《大话设计模式》,《重构 改善既有代码的设计》,《effective java》《深入理解Java虚拟机》《Java并发编程实战》《深入理解计算机系统》
3、java基础知识汇总
1、java中的四
面相对象的四大特征:抽象,封装,继承,多态
2、j2ee原始体系结构:
3、变量
变量其实就是在内存中开辟的一块用于存储数据的空间。
对于变量的使用来说大致分为以下几个步骤:
1)变量的声明:想要使用变量就要先声明变量,确定它的类型。(类型有基本类型:byte->short->char->int->long->float->double,boolean;引用类型:除去基本类型以外其余都是引用类型,比如String,Integer,数组,list,对象等。引用类型有四种方式:强引用,弱引用,软引用,虚引用。
强引用(Final Reference):默认引用类型,类似于Object obj=new Object()这样的引用。特点如下:
1、GC在任何时候都不会回收强引用,即便抛出了OOM错误。
2、可以直接访问对象。
3、可能存在导致内存泄露的情况.
弱引用(Weak Reference):用来描述非必须的对象,它的生命周期是在产生至下一次GC工作之前,当GC工作时,无论内存情况如何都会对此类引用进行回收。被回收的此类应用会进入到注册引用队列。弱引用的相关实际案例可以参考WeakHashMap,后期补充
软引用(Soft Reference):软引用一般用来表达一些有用但是非必须的对象,GC会在内存不够的情况下进行回收
虚引用(Phantom Reference):最弱的一种引用类型,随时都有可能被GC回收,必须与引用队列一起使用,作用在于跟踪垃圾回收过程)
2、变量的命名:符合java命名规范(首字母不能以数字开头,不可使用保留字,大小写敏感,可以有数字,字母,_和$组成),符合驼峰命名,符合标识符命名规范,言简意赅,意思清晰
3、变量的初始化:未被初始化的变量是无法使用的,初始化可以在变量声明时就初始化,也可以在首次使用之前进行初始化.
4、变量的使用:进行存取,计算等操作。
变量使用的常见问题:
变量在使用的过程中,常见问题总结为如下几点:
1)使用未经声明的变量。
2)使用不符合Java标识符命名规则的变量。
3)使用未经初始化的变量。
4)变量的赋值与变量的类型不匹配
整数类型在使用的过程中,常见的问题有以下几点:
1)整数直接量超出了整数的范围。
2)关于整数的除法:两个整数相除,会舍弃小数的部分,结果也是整数。
3)整数运算的溢出:两个整数进行运算时,其结果可能会超过整数的范围而溢出。
4)表示long直接量,需要以 L 或 l 结尾。
浮点类型在使用的过程中,常见的问题有以下几点:
1)浮点数的直接量为double类型。
2)浮点数存在舍入误差问题。
char类型在使用的过程中,常见的问题有以下几点:
1)字符类型存储中文。
2)char类型的值可以作为整数类型直接使用。
数据类型转换在使用的过程中,常见的问题有以下几点:
1)强制转换时的精度丧失和溢出。
2)数值运算时的自动转换。
3)byte、char、short转换为int的问题。
4、运算符
补充点:“+”有两种运算规则,一种是两端为数字则为数学加法运算,另外一种是实现字符串的连接,也可以实现字符串与其他数据类型的“相连”。上述代码中,字符串之前的运算按照加法运算,字符串之后的运算按照字符串相连。
5、方法
1.用于封装一段特定的业务逻辑功能
2.方法应尽可能独立,一个方法只干一件事
3.方法可以被反复的调用多次
4.较少代码重复,维护方便,便于协作开发
定义方法的5个要素:
修饰词 返回值类型 方法名 参数列表 方法体
System.currentTimeMillis() 方法:该方法返回1970年1月1日零点到此时此刻所经历的毫秒数,其数据类型为long,经常用于计时操作。示例:
以下代码的功能为计算1累加到1000000的所耗的时间,代码如下所示:
- public static void main(String[] args) {
- //开始时间
- longstartTime = System.currentTimeMillis();
- //计算从1加到1000000的和
- int sum = 0;
- for (int i = 1; i <= 1000000; i++) {
- sum+=i;
- }
- //结束时间
- longendTime = System.currentTimeMillis();
- //输出耗时
- System.out.println("耗时:"+(endTime-startTime)+"毫秒");
- }
6、枚举
enum修饰,一般用于常量的定义,个人感觉比常量类好用。
示例:
@Getter
@AllArgsConstructor
public enum DemoEnum(){
CONSTANT_DEMO("constant","常量");
private String code;
private String desc;
}
7、访问控制修饰符
public:公有,所有类都可以访问
default:默认修饰符,同包内访问
protected:保护型。同包内以及继承了此类的外包类可以访问
private:私有类,只有本类内可以访问。
8、静态 static
静态方法不能直接访问实例变量
静态块:
属于类,被static修饰,在类加载期间自动执行加载,且只加载一次。一般用于加载静态资源。
9、接口
1.是一个标准,规范
2.是一种数据类型(引用类型)
3.由interface定义,只能包含常量和抽象方法
4.接口不能被实例化
5.接口需要被实现(implements),被实现后必须重写接口的所有抽象方法
6.一个类可以实现多个接口,如果又继承又实现,一定要先继承后实现
7.接口可以继承接口
10、抽象类
abstract修饰,平常类有的,它都可以有。且extends抽象类时可以选择override方法,不需要全部override;方法为抽象方法时,所在的类必须为抽象类,且不能被实例化。
11、继承
一个类只能继承一个父类;默认情况下所有类都是继承了Object类。
1)子类继承父类的成员变量
能够继承public,protected成员变量,不能继承private成员变量;
父类的包访问权限成员变量,只有子类在与父类同包的情况下才能继承;
继承后,如果子类有和父类相同名称的成员变量,子类的成员变量会屏蔽掉父类的,如果想 要访问父类的,可以用super关键字
2)子类继承父类的方法
访问修饰符的继承与成员变量一致;
如果子类有与父类相同名称的方法,则会覆盖掉父类方法,即重写或重载;调用父类方法,可以使用super关键字。
3)构造器
子类不能继承父类的构造器;父类的构造是子类来引用的,不是继承的
12、重载与重写
重载:
存在于子父类和同类中;方法名称相同,但参数类型,参数顺序,参数个数至少有一个是不一致的;只有返回类型不一致时不能重载;对访问权限修饰符无要求
重写:
存在于子父类中;方法名称,返回值,参数类型,顺序,个数都相同;访问权限修饰符只能小于等于父类的修饰符;如果父类中有final修饰的方法,则不能被重写;(父类返回类型是void或基本类型时,子类必须的返回类型必须相同,返回类型是引用类型时,可以是小于等于父类的)
区别对比:
区别点
|
重载(Overloading)
|
重写(Overiding)
|
定义
|
方法名称相同,参数的类型,顺序或个数不同
|
方法名称、参数类型、返回值类型全部相同
|
权限
|
对权限没要求
|
被重写的方法不能拥有更严格的权限
|
范围
|
发生在继承类,同类中
|
发生在继承类中
|
13、JDBC
1)使用步骤:
加载驱动类:
Class.forName("com.mysql.jdbc.driver");
创建连接
Connection con=DriverManager.getConnection(url,name,password);
创建statement实例
1、执行静态SQL语句。通常通过Statement实例实现。
Statement ste=con.createStatement();
2、执行动态SQL语句。通常通过PreparedStatement实例实现。
PreparedStatement pstmt = con.prepareStatement(sql) ;
3、执行数据库存储过程。通常通过CallableStatement实例实现。
CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}") ;
执行sql
1、ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句 ,返回一个结果集(ResultSet)对象。
ResultSet rs = stmt.executeQuery(“SELECT * FROM …”) ;
2、int executeUpdate(String sqlString):用于执行INSERT、UPDATE或 DELETE语句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等
int rows = stmt.executeUpdate(“INSERT INTO …”) ;
3、execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合的 语句。 具体实现的代码:
boolean flag = stmt.execute(String sql) ;
处理结果
关闭连接
操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声 明顺序相反:1、关闭记录集2、关闭声明3、关闭连接对象
2)对事务的操作
事务:
满足以下四点特征的数据库访问叫做事务
-原子性:事务是一个完整的过程,要么成功,要么失败
-一致性:事务访问前后数据一致
-隔离性:事务访问过程中,所操作的数据会被锁住,直到操作完成
-持久性:事务一完成,结果就永久有效
操作方法:
在创建连接之后加上:
conn=DBUtil.getConnection();
//取消自动提交事务
conn.setAutoCommit(false);
在执行完所有SQL之后加上:
//手动提交事务
conn.commit();
在异常捕获中加上:
//发生异常时回滚事务
DBUtil.rollBack(conn);
此处的DBUtil是事先封装好的一些对于事务的回滚操作。参考方法:
//回滚事务
public static void rollBack(Connection conn){
if(conn!=null){
try {
conn.rollback();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("回滚事务失败?",e);
}
}
}
3)补充一个点:获取返回数据的总列数
conn= DBUtil.getConnection();
System.out.println(conn);
Statement smt=conn.createStatement();
String sql="select * from emps where empno='"+id+"'";
ResultSet res=smt.executeQuery(sql);
//获取返回数据的总列数
ResultSetMetaData rsmd = res.getMetaData() ;
while(res.next()){
for(int i=1;i< rsmd.getColumnCount();i++){
System.out.println(res.getString(i));}
}
14、线程
很重要,单独整理一遍
15、final,finally,finalize
final: 修饰符。
被此修饰符修饰的类不能被继承;
被此修饰符修饰的变量不能被修改,只能读取;
被此修饰符修饰的方法只能使用,可以被重载,不能被重写;
此修饰符不能修饰抽象类;
finally: 捕获异常后的清除操作。
finalize:一个方法;主要是在GC将对象删除之前,先对对象调用一下finalize方法,来确定对象是否被引用
16、session与cookie
服务端可以生成一个session,然后把对应的sessionId以cookie的形式发送给客户端。
session方法:
1)HttpSession s=request.getSession(boolean flag);
-HttpSession是一个接口;
-当flag为true时:先查看请求中有没有SessionId,如果没有,服务器则创建一个Session对象;如果有则根据SessionId去查找对应的Session对象,找到则返回,找不到则创建一个新的
-当flag为false时,没有SessionId或者根据SessionId没有找到对应的Session对象,都返回null;
-一般使用HttpSession s=request.getSession();这样的话不管任何情况都可以得到一个Session对象
2)对象的操作
-绑定:session.setAttribute(String name;Object object);
-获取绑定对象 session.getAttribute(String name);
-移除绑定对象 session.removeAttribute(String name);
3)删除session对象
session.invalidate();
4)Session超时
指的是:Web服务器会将空闲时间过长的Session对象删除掉,以节省服务器内存空间资源。web服务器缺省的超时时间限制:一般是30分钟。修改Session的缺省时间限制,有如下两种方式:
1. 通过修改tomcat中 conf/web.xml 文件的设置,代码如下所示:
- <session-config>
- <session-timeout>30</session-timeout>
- </session-config>
2.通过编程的方式来修改,通过调用Session对象的setMaxInactiveInterval方法来修改,该方法的声明如下所示:
- void setMaxInactiveInterval ( int seconds ){}
cookie方法:
1)创建:
String user=request.getParameter("user");
//Cookie中只能存一条数据,且只能存字符串
Cookie c1=new Cookie("user",user);
2)获取:
//浏览器访问时自动传入保存的Cookie
Cookie[] cookies=req.getCookies();
if(cookies != null) {
res.setContentType("text/html;charset=utf-8");
PrintWriter p=res.getWriter();
for(Cookie c : cookies) {
//System.out.println(c.getName()+"按"+c.getValue());
p.println(c.getName()+":"+c.getValue());
}
p.close();
}
3)发送:
//将Cookie绑定到reponse中,服务器响应时自动发送
response.addCookie(c1);
4)设置有效路径
Cookie c=new Cookie("name","test");
c.setPath("/appName");
response.addCookie(c);
5)编码问题
Cookie只能保存合法的ASCII字符,若要保存中文,则需要将中文编码成ASCII字符
Cookie c=new Cookie("city",URLEncoder.encode("北京“,"utf-8");
解码:
Cookie[] cookies=req.getCookies();
if(cookies != null) {
Cookie c=Cookie[0];
String value=c.getValue();
value=URLEncoder.decode(value,"utf-8");
}
6)生存时间
默认情况下,浏览器会将Cookie保存在内存中,只要浏览器不关闭,就一直存在;
如果希望浏览器关闭了还存在,则需要设置过期时间:
void Cookie.setMaxAge(int seconds);
seconds>0:浏览器保存Cookie的最长时间为seconds的值,超过这个时间,浏览器就会删除,这种情况下Cookie是保存在硬盘上的;
seconds=0:响应发送会客户端时,就会删除原有Cookie;
seconds<0:缺省值。
浏览器禁用Cookie解决方法:
重写URL:即让浏览器在访问服务器时,不再使用原有地址,而是在原有地址后面加上SessionId:
response.encodeRedirectURL(java.lang.String url) 用于对sendRedirect方法后的url地址进行重写。
response.encodeURL(java.lang.String url)用于对表单action和超链接的url地址进行重写
17、equals与==区别
值类型都是用==判断相等性,医用对象需要使用equals;equals会比较引用对象的引用地址以及值是否都相等
18、List与Set区别
List:元素有放入的顺序;元素可以重复;list支持for循环,也就是通过下标来遍历,也可以用迭代器,
Set:元素没有放入的顺序,但是位置是固定的,元素的位置是通过HashCode决定的;元素不可以重复,当有重复元素时,会覆盖前一个;加入Set 的Object必须定义equals()方法 ,set只能用迭代,因为他无序,无法用下标来取得想要的值。
Set和List对比:
Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。
19、内部类
内部类大致分为:成员内部类,局部内部类,匿名内部类,静态内部类。
1、成员内部类:
成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。
不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:
1
2
|
外部类.this.成员变量
外部类.this.成员方法
|
虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问:
内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。比如上面的例子,如果成员内部类Inner用private修饰,则只能在外部类的内部访问,如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。这一点和外部类有一点不一样,外部类只能被public和包访问两种权限修饰。我个人是这么理解的,由于成员内部类看起来像是外部类的一个成员,所以可以像类的成员一样拥有多种权限修饰。
2.局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。
3、匿名内部类
匿名内部类也是不能有访问修饰符和static修饰符的。
匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为Outter$1.class。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
4、静态内部类
静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。