java基础知识汇总(持续更新中....)

1.java四大特性:抽象、继承、封装,多态

  构造函数:

http://blog.csdn.net/qq_33642117/article/details/51909346

 

2.java数据基本类型:byte  short  int  long  double  float  char  boolean,

包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

Integer :整型变量的值在-128-127之间时不会new新的对象,而是直接引用常量池中的Integer对象
,当增形变量的值不在-128-127之间时直接new新对象  

 

public class Test03 {

    public static void main(String[] args) {
        Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;

        System.out.println(f1 == f2);//结果为true
        System.out.println(f3 == f4);//结果为false
    }
}

3.静态代码块:静态代码块在类加载时执行,且只执行一次
ps:  在new对象之前加载   例:

 

 

public class StaticTest {
	public static void main(String[] args){
		new Test1();
		new Test1();
	}
}
class Test1{
	public Test1(){
		System.out.println("Test1构造方法");
	}
	
	static{
		System.out.println("我是静态代码块,先执行我!!");			
	}
	
}
执行结果:
我是静态代码块,先执行我!!
Test1构造方法
Test1构造方法

静态方法是直接被类调用,不可以被对象调用:

 

public class Student {  
    public static void main(String[] args) {  
        // TODO Auto-generated method stub  
  
    	Student stu1=new Student();  
        stu1.method3();  
        Student.method1();  
        Student.method2();  
    }  
      
    public static void method1(){  
        System.out.println("123");  
    }  
    public static void method2(){  
        System.out.println("456");  
    }  
    public void method3(){  
        System.out.println("789");  
    }  
  
}  


 

 

 

4.jvm内存中栈stack 堆heap 方法区method area

栈:定义基本数据变量,对象引用,函数调用的现场保存
堆:new关键字  创建对象    GC(垃圾收集器管理)的主要区域
方法区和堆都是各个线程共享的内存区域,

String str = new String("hello");
str放在栈中,new的字符串对象放在堆中, hello放在方法区的常量池中

 

https://www.cnblogs.com/dingyingsi/p/3760730.html

 

 

5.StringBuffer与StringBuider区别   

StringBuffer支持并发操作,线程安全,适合多线程,  作用:String是不可改变
其属性不可改变,当对String对象操作的时候可能会产生大量的中间字符串对象,造成
因此使用可以改变的StringBuffer
StringBuider 不支持并发操作,线程不安全,不适合多线程,单线程中性能高

 

https://www.cnblogs.com/A_ming/archive/2010/04/13/1711395.html

 

 

str.intern() 的作用:会将共享池中的字符串与外部的字符串s进行比较,如果共享池中已经有
与之相等的字符串,则不会将外部的字符串放入共享池,返回的也是共享池中的
字符串,如果不同则将外部的字符串放入共享池中,并返回其字符串的句柄

-------这样做的好处就是节省空间。

 

java内存分配机制:

https://www.cnblogs.com/dingyingsi/p/3760730.html 
http://blog.csdn.net/tutngfei1129287460/article/details/7383480 


 

例:  个人见解,不知道是否正确,如果有大神发现错误,还望指正

 

 //常量池中本来就不含有jva字符,所以new的jva会放入常量池,属于同一个对象,返回true  先new一个SringBuffer对象,此时单独开辟一个区域,然后调用append方法
	      //拼接字符串(相当于对字符串的拼接而不是new的对象了),将拼接完成的字符串放入常量池,此时new出来的对象就是需要放入常量池的,返回true
	      		String s1 = new StringBuilder("j").append("va").toString();
	      		System.out.println(s1.intern()==s1);//true
	      		
	      		//常量池中本身就有字符串java所以返回的并不是同一个字符串 s2.intern()返回常量池中的
	      		//java s2为new的字符所以不相等返回false
	      		String s2 = new StringBuilder("ja").append("va").toString();
	      		System.out.println(s2.intern()==s2);//false
	      		
	      		//返回false因为new出来的对象单独开辟一块区域放在java堆中,与常量池中的不同和
	      		String s3 = new StringBuilder("Programming").toString();
	      		System.out.println(s3.intern()==s3);//false


 

 

对于字符串的存储:

 

public static void main(String[] args){
		String s1 = "Programming";  
        String s2 = new String("Programming");
        String s3 = "Program";
        String s4 = "ming";
        String s5 = "Program" + "ming";
        String s6 = s3 + s4;
		String s7 = new StringBuilder("Programming").toString();
		String s8 = new StringBuilder("Program").append("ming").toString();
		
		
        System.out.println(s1 == s2); //false  s1被赋予字符串Programming后发现常量池中并没有这一字符串,就将其
        //放入常量池
        System.out.println(s1 == s5);//true   //字符串的+操作其本质是创建了StringBuilder对象进行append操作,
        //然后将拼接后的StringBuilder对象用toString方法处理成String对象,s5拼接完成后发现常量池中已经有字符串Programming
        //所以s5直接取常量池中的字符串所以返回true
        System.out.println(s1 == s6);//false    这个暂时没搞懂
        System.out.println(s1 == s5.intern());//true
        System.out.println(s1 == s6.intern());//true
        System.out.println(s2 == s2.intern());//false  因为s2  new了一个字符串对象,在堆中单独开辟一块区域,并不是常量池
                                                //中对象 所以返回false
        System.out.println(s7.intern()==s7);//false //返回false因为new出来的对象单独开辟一块区域放在java堆中,与常量池中的不同
        System.out.println(s8.intern()==s8);///false   这个单独执行时是true  放在这里一起执行是false,个人推测
        //是因为常量池中已经存在字符串Programming,而s8是new出来的,他拼接完成之后,其地址与常量池中字符串的地址
        //不同,返回false
   
	}


 

 

 

 

6.泛型:

https://www.cnblogs.com/lwbqqyumidi/p/3837629.html

 

7.java事务:事务通常用在数据库的操作中,在一个事务中,必须一个事物的所有操作全部成功,这个事物才算成功,如果事务中的任一步失败了,整个事务都会失败,例如:

在A--->B的转账操作中,步骤有1.A账户减去100元     2. B账户增加100元     如果A的账户已经划去了100元但是B的账户增加100元失败则整个交易取消,A的账户的100元不会扣除

http://blog.csdn.net/sinat_33536912/article/details/51200630

8.方法重写(OverRide)与重载(OverLoad):

重写一般用于继承的时候,子类继承父类的方法,并对父类的方法进行重写。

重载一般是用于在一个类内实现若干重载的方法,这些方法的名称相同而参数形式不同

 

https://www.cnblogs.com/lonelyDog/archive/2011/11/16/2251011.html

9.java内部类与静态内部类:都是在一个外围类内再写一个类,故称为嵌套类:

静态类与费静态类的区别:

https://www.cnblogs.com/itdev/p/5665531.html

 

内部类:

class OuterClass {  
    ...  
    class NestedClass {  
        ...  
    }  
}  
静态内部类:
class OuterClass {  
    ...  
    class InnerClass {  
        ...  
    }  
  
    static class StaticNestedClass {  
        ...  
    }      
}  

 

内部类与静态内部类实例化的方法有所不同:内部类要通过外部类的实例化对象进行实例化

例:

OuterClass outerObject = new OuterClass();  
OuterClass.InnerClass innerObject = outerObject.new InnerClass();  

静态内部类:直接实例化对象

 

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();  

 

参考:http://blog.csdn.net/iispring/article/details/46490319


10.值传递与引用传递:

先说结论:1.基本类型传值,对形参的修改不会影响实参

2.引用类型(非基本类型)引用,同一个对象的形参和实参指向同一个地址,所以对形参的修改写会影响到实参

3.String,Integer、Double等几个及基本类型的包装类的对象不可改变,可以理解为传值,最后的操作不会修改实参对象。

(1)基本类型的变量创建出来其参数并不指向某一内存而是就等于这个值本身,

而引用类型的的变量它指向一个内存地址,内存地址中存放这个对象本身

(2)

值传递:

方法调用时,实际参数把它的值传递给对应的形式参数,函数接收的是原始值的一个copy,此时内存中存在两个相等的基本类型,即实际参数和形式参数后面方法中的操作都是对形参这个值的修改,不影响实际参数的值

引用传递:

也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,函数接收的是原始值的内存地址;
在方法执行中,形参和实参内容相同,指向同一块内存地址,方法执行中对引用的操作将会影响到实际对象

例:

public class Javabianliang {
	public static void main(String[] args){
		TestClass tc = new TestClass();
		Test t = new Test();
		int a = 50;
		//调用前
		System.out.println(a);
		System.out.println(t.a);
		//调用后  对象的值被改变  基本类型 int的值未被改变
		tc.value1(a);
		System.out.println(a);
		tc.value2(t);
		System.out.println(t.a);
	}
	
}

class TestClass{
	public void value1(int a){
		a = a + 1;
	}
	
	public void value2(Test test){
		test.a = test.a + 1;
	}
}
class Test{
	int a = 20;
}

 

 

https://www.zhihu.com/question/31203609


 

 

11.进程与多线程:

 

https://www.zhihu.com/question/25532384
多线程与多进程:http://blog.csdn.net/luoweifu/article/details/46595285

 

进程:是一个执行过程,动态的概念 --->会分配内存
线程:是进程的一个单元,线程是系统最小的执行单元

线程锁详解

参考:同步锁synchronized的使用详解:http://blog.csdn.net/luoweifu/article/details/46613015

1.synchronized只锁定同一个对象中的线程,不同对象的线程无法锁定。锁定的对象只能由当前线程执行,其他线程不能执行,直到当前线程被释放。

2.当一个线程访问对象的一个synchronized(this)同步代码块时,另一个线程可以访问这个对象中的非synchronized(this)代码块

3.给一个对象加锁,在run方法中可对一个对象加锁,是的同时只能由一个线程访问此被加锁的对象,其他试图访问account对象的线程将会阻塞,直到该线程访问account对象结束

4.修饰一个方法:

public synchronized void method()
{
}
    在用synchronized修饰方法时要注意以下几点: 

 

      (1) synchronized关键字不能继承。 

(2)在定义接口方法时不能使用synchronized关键字。

(3)构造方法不能使用synchronized关键字,但可以使用synchronized代码块来进行同步。 

5.修饰一个静态方法:

静态方法是属于类的而不属于对象的。同样的,synchronized修饰的静态方法锁定的是这个类的所有对象,即此类的所有的对象都受这个同步锁的约束,这与1中的情况不同。

6.修饰一个类,作用同5一样

java中线程锁:一个对象只能有一个锁,当一个线程获得锁之后,其他线程就无法获得,直到这个线程被释放,重要作用就是:防止多个线程同时对一个数据进行处理造成错误

Thread中的sleep、wait、yield、notify、notifyall、join方法

参考:

java线程中yield(),sleep(),wait()区别详解

 

sleep()方法会让当前线程暂停执行指定的时间,将执行机会(cpu)让给其他线程,但是对象的锁依然保持,因此休眠时间结束后会自动恢复,且sleep方法暂停后,其他线程都可以有执行的机会,包括低优先级的线程

yield方法与sleep方法类似,但是不能指定用户暂停多长时间,且只能让通优先级的线程有执行的机会

join,使调用join方法的线程执行完毕后,其他线程才能够继续执行,即顺序执行

例:

 t1.start();
        //等待t1结束,这时候t2线程并未启动
        t1.join();
        
        //t1结束后,启动t2线程
        t2.start();
        //等待t2结束
        t2.join();

 

wait()、notify()、notifyall()都是是object类的方法,wait会让当前线程放弃对象的锁(线程暂停执行),进入对象等待池,只有调用对象的notify方法才能唤醒等待池中的线程进入等锁池,如果线程重新获得对象的锁就可以进入就绪状态。

notifyall方法则是将对象等待池中的所有等待那个对象的线程放到等锁池中

线程的创建方式:1.继承Thread类实现其中的run方法,在run方法中实现执行代码

 

public class JavaThread extends Thread{
	@Override
	public void run() {
		boolean flag= true;
		int i = 0;
		while(flag){
			System.out.println(getName()+"我是线程1");
			if(i++==100){
				break;
			}
		}
		
		System.out.println("我要走了");
	}
此方法需要用Thread类new一个线程,然后调用start()方法启用线程

 

 

Thread th = new JavaThread();
		th.setName("哈哈哈");
		th.start();

 

2.实现runnable接口,实现其中的run方法

 

class Actress implements Runnable{
	@Override
	public void run() {
		
		boolean flag= true;
		int i = 0;
		while(flag){
			System.out.println(Thread.currentThread().getName()+"我是线程2");
			if(i++==100){
				break;
			}
		}
		
	}
	
}
新建线程:

 

 

Thread t1 = new Thread(new Actress());
		actressTh.start();

3.实现Callable接口,该接口中的call方法可以在线程执行结束时产生一个返回值

 

public class JavaThread {
	public static void main(String[] args) {
		/**
		 * 采用FutureTask 实现Callable的调用,
		 */
		int sum=0;
		CallThread ct = new CallThread(3);
		//执行 Callable 方式,需要 FutureTask 实现类的支持,
		FutureTask<Integer> result = new FutureTask<>(ct);
		new Thread(result).start();
		try {
			//调用Future对象的get方法获取线程中call方法返回的数据
			sum = result.get();
			System.out.println(sum);
		} catch (Exception e) {
			e.printStackTrace();
		} 
		
		/**
		 * 采用线程池实现Callable方法的调用
		 */
//		List<Future<Integer>> list = new ArrayList<>();
		//采用线程池,最大线程数为10
//		ExecutorService service = Executors.newFixedThreadPool(10);
//		for(int i=0;i<10;i++){
		    //service.submit()会返回一个Future对象,将Future对象存入list
//			list.add(service.submit(new CallThread(3)));
//		}
//		int sum = 0;
//		for(Future<Integer> future:list){
//			try {
			//调用Future对象中的get方法获取线程中call方法的返回值
//				sum += future.get();
//			} catch (InterruptedException | ExecutionException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//		}
		//System.out.println(sum);
	}
}

class CallThread implements Callable<Integer>{
	private int Test;
	
	public CallThread(int Test) {
		this.Test = Test;
	}
	@Override
	public Integer call() throws Exception {
		int sum = 0;
		for(int i=1;i<=Test;i++){
			sum+=i;
		}
		return sum;
	}
	
}

线程池:
线程池就是就像一个容器,而这个容器就是用来存放线程的,且有固定的容量
如果没有线程池,当需要一个线程来执行任务时就需要创建一个线程,我们设创建线程的时间为t1,执行线程的时间为t2,销毁线程的时间为t3。每次创建线程到线程销毁时间是t1+t2+t3

而线程池技术会将t1和t3时间的操作安排在在服务器程序的启动和结束的时间段或者一些空闲的时间段并且线程池中会始终保持有其容量大小的线程存在,当需要使用线程时就从线程池中调用,这大大节省了资源,提高了效率

 

[java] view plain copy
 
  1. 线程池详解参考:  
  2. http://blog.csdn.net/hsuxu/article/details/8985931  
ExecutorService:

 

ExecutorService service= Executors.newFixedThreadPool(100);
方法:
execute(Runnable)  
接收一个Runnable对象作为参数,并且以异步的方式执行他,但是这和执行后不会返回执行后的结果
submit(Runnable)  
同样接收一个runnable对象作为参数,但是会返回一个Future 对象。这個 Future 对象可以用于判断 Runnable 是否结束执行。
扩展:future对象的使用及作用:简单来说就是当我们需要某一个线程A的执行结果(即要想进行下一步操作必须要A这一线程执行完毕)
才能继续执行接下来的操作时,一般的runnable方法只能调用join方法阻塞主线程B来等待线程A执行完毕,这样就造成了时间浪费无法体现多线程的优势,而使用future可以在执行线程A时同时异步执行其他不需要A的结果的线程,且可以时刻返回线程A的执行状态,看A是否执行完毕
例子:假如你突然想做饭,但是没有厨具,也没有食材。网上购买厨具比较方便,食材去超市买更放心。
实现分析:在快递员送厨具的期间,我们肯定不会闲着,可以去超市买食材。所以,在主线程里面另起一个子线程去网购厨具。
我们要想做菜,必须要厨具和食材都齐全才能开始,若购买厨具是最耗时的环节,我们不调用join方法等待购买厨具线程执行完毕就会出现厨具还没买到就开始做菜的错误
所以若使用runnable方法我们只能等待购买厨具这个线程执行完毕才能执行其他方法,而使用future对象,我们就可以在购买厨具的同时进行食材的购买

[java] view plain copy
 
  1. 具体实现及功能看文章:https://www.cnblogs.com/cz123/p/7693064.html  

Callable对象:
submit(Callable) 
submit(Callable) 和方法 submit(Runnable) 比较类似,但是区别则在于它们接收不同的参数类型。Callable 的实例与 Runnable 的实例很类似,但是 Callable 的 call() 方法可以返回一个结果。方法 Runnable.run() 则不能返回结果。Callable 的返回值可以从方法 submit(Callable) 返回的 Future 对象中获取。
invokeAny(...)  
invokeAll(...)  
用于线程池的关闭:
shutdown():不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务
shutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务
isTerminated方法:判断所有子线程是否全部执行完毕并关闭,如果全部执行完毕则返回true。注意除非首先调用shutdown或shutdownNow,否则isTerminated永不为true。
若关闭后所有任务都已完成,则返回true。
[java] view plain copy
 
  1. 详解参考:http://blog.csdn.net/bairrfhoinn/article/details/16848785  


12.静态变量与实例变量

静态变量是用static修饰的变量,其为全局变量,所有的实例对象引用该变量时都指向同一地址,任一个对象对其值做出改变后,其他变量再引用就是已经改变的值

实例变量未用static修饰,为对象私有,一个对象改变其值不影响别的变量的引用

 

public class Javabianliang {
	public static void main(String[] args){
		StaticBianliang sbl = new StaticBianliang();
		System.out.println("赋值前sbl.a="+sbl.a);
		System.out.println("赋值前sbl.b="+sbl.b);
		sbl.a = 20;
		sbl.b = 30;
		System.out.println("赋值后sbl.a="+sbl.a);
		System.out.println("赋值后+sbl.b="+sbl.b);

		StaticBianliang sb2 = new StaticBianliang();
		System.out.println("赋值后sb2.a="+sb2.a);
		System.out.println("赋值后sb2.a="+sb2.b);
	}
}

class StaticBianliang{
	static int a = 1;
	int b = 2;
}

输出结果:

 

 

赋值前sbl.a=1
赋值前sbl.b=2
赋值后sbl.a=20
赋值后+sbl.b=30
赋值后sb2.a=20
赋值后sb2.a=2

http://blog.csdn.net/daochugundepidan/article/details/48557489


 

 

13.克隆:浅克隆与深克隆

 

https://www.cnblogs.com/Qian123/p/5710533.html

14.关于关键字:throws、throw、try、catch、finally分别如何使用?以及try、catch、finally的执行先后顺序

try catch通常成对存在,在try块中执行一段程序,若程序不出错则跳过catch块,若try块内抛出异常则catch块执行

public class JavaException {  
	public static void main(String[] args) {  
		try{  
			System.out.println("我是try块");  
			int i = 1/0;  
			System.out.println("try快出错后的代码是否执行?");  
		}
		catch (Exception e){  
			System.out.println("try出错,catch块执行");  
		}  
	}  
}  


 

throw语句用来明确的抛出一个异常,执行到这一步必然会抛出异常;

 

throws用来声明一个方法可能抛出的异常,并不一定会抛出,只有在出现异常时才抛出;

finally块的执行在try和catch块返回值之前执行

 

关于finally的详细解析http://blog.csdn.net/jiasanshou/article/details/6996932/


15.TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素? 

 

参考java面试题全集(上)第56题

TreeSet实现比较:

Student类中实现Comparable接口

 

public class Student implements Comparable<Student> {
	private String name;
	private int age;
	
	public Student(String name,int age) {
		this.name= name;
		this.age = age;
	}
	
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}

	@Override
	public int compareTo(Student o) {
		
		return this.age - o.age; //比较年龄升序
	}
}
主函数测试

 

 

public class TestStudent1 {
	public static void main(String[] args) {
		/**
		 * age不能有重复的值,因为在Student类中调用了方法对age排序
		 * treeSet要求存放的对象所属类(即Student中)必须实现Comparable接口
		 * 该接口提供了比较元素的compareTo()方法,当插入元素时会回调该方法比较元素的大小。
		 */
		Set<Student> set = new TreeSet<>();
		set.add(new Student("tonghao", 20)); //
		set.add(new Student("tonghao", 21));
		set.add(new Student("Bruce LEE", 60));
	    set.add(new Student("Bob YANG", 22));
		
		for(Student stu : set){
			System.out.println(stu);
		}
		
	}
}
List实现比较

 

 

public class Student1 {
	private String name;
	private int age;
	
	public Student1(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}

	@Override
	public String toString() {
		return "Student1 [name=" + name + ", age=" + age + "]";
	}

	
	
}
public static void main(String[] args) {
		/**
		 * Collections工具类的sort方法有两种重载的形式,第一种要求传入
		 * 的待排序容器中存放的对象比较实现Comparable接口以实现元素的比
		 * 较(跟上边TreeSet的实现方法一样);
		 * 
		 * 这里使用的是第二种
		 * 第二种不强制性的要求容器中的元素必须可比较,但是要求传入
		 * 第二个参数,参数是Comparator接口的子类型(需要重写compare方
		 * 法实现元素的比较)
		 */
		List<Student1> list = new ArrayList<>();
		list.add(new Student1("zhangsan", 21));
		list.add(new Student1("lisi", 21));
		list.add(new Student1("wanger", 23));
		list.add(new Student1("zhengwu", 24));
		Collections.sort(list, new Comparator<Student1>() {

			@Override
			public int compare(Student1 o1, Student1 o2) {
				return o1.getName().compareTo(o2.getName());
			}
		});
		for(Student1 stu :list){
			System.out.println(stu);
		}
	}
}

16.Java web中转发forward和重定向redirect的区别:

参考:https://www.cnblogs.com/Qian123/p/5345527.html


forward(转发):
是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,因为这个跳转过程实在服务器实现的,并不是在客户端实现的所以客户端并不知道这个跳转动作,所以它的地址栏还是原来的地址.

redirect(重定向):
是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.

转发是服务器行为,重定向是客户端行为。

区别:
1. 从地址栏显示来说
forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.

2. 从数据共享来说
forward:转发页面和转发到的页面可以共享request里面的数据.
redirect:不能共享数据.

3. 从运用地方来说
forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等

4. 从效率来说
forward:高.
redirect:低.

 

17.java web九大内置对象

1、request对象
request 对象是 javax.servlet.httpServletRequest类型的对象。 该对象代表了客户端的请求信息,主要用于接受通过HTTP协议传送到服务器的数据。(包括头信息、系统信息、请求方式以及请求参数等)。request对象的作用域为一次请求。

2、response对象
response 代表的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。response对象也具有作用域,它只在JSP页面内有效。

3、session对象
session 对象是由服务器自动创建的与用户请求相关的对象。服务器为每个用户都生成一个session对象,用于保存该用户的信息,跟踪用户的操作状态。session对象内部使用Map类来保存数据,因此保存数据的格式为 “Key/value”。 session对象的value可以使复杂的对象类型,而不仅仅局限于字符串类型。

4、application对象
 application 对象可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效。与session对象相比,application对象生命周期更长,类似于系统的“全局变量”。

5、out 对象
out 对象用于在Web浏览器内输出信息,并且管理应用服务器上的输出缓冲区。在使用 out 对象输出数据时,可以对数据缓冲区进行操作,及时清除缓冲区中的残余数据,为其他的输出让出缓冲空间。待数据输出完毕后,要及时关闭输出流。

6、pageContext 对象
pageContext 对象的作用是取得任何范围的参数,通过它可以获取 JSP页面的out、request、reponse、session、application 等对象。pageContext对象的创建和初始化都是由容器来完成的,在JSP页面中可以直接使用 pageContext对象。

7、config 对象
config 对象的主要作用是取得服务器的配置信息。通过 pageConext对象的 getServletConfig() 方法可以获取一个config对象。当一个Servlet 初始化时,容器把某些信息通过 config对象传递给这个 Servlet。 开发者可以在web.xml 文件中为应用程序环境中的Servlet程序和JSP页面提供初始化参数。

8、page 对象
page 对象代表JSP本身,只有在JSP页面内才是合法的。 page隐含对象本质上包含当前 Servlet接口引用的变量,类似于Java编程中的 this 指针。

9、exception 对象
exception 对象的作用是显示异常信息,只有在包含 isErrorPage="true" 的页面中才可以被使用,在一般的JSP页面中使用该对象将无法编译JSP文件。excepation对象和Java的所有对象一样,都具有系统提供的继承结构。exception 对象几乎定义了所有异常情况。在Java程序中,可以使用try/catch关键字来处理异常情况; 如果在JSP页面中出现没有捕获到的异常,就会生成 exception 对象,并把 exception 对象传送到在page指令中设定的错误页面中,然后在错误页面中处理相应的 exception 对象。




 

posted @ 2018-01-01 13:44  非我非非我  阅读(198)  评论(0编辑  收藏  举报