day24Java进阶知识解析.docx

上传人:b****5 文档编号:5979092 上传时间:2023-01-02 格式:DOCX 页数:25 大小:23.81KB
下载 相关 举报
day24Java进阶知识解析.docx_第1页
第1页 / 共25页
day24Java进阶知识解析.docx_第2页
第2页 / 共25页
day24Java进阶知识解析.docx_第3页
第3页 / 共25页
day24Java进阶知识解析.docx_第4页
第4页 / 共25页
day24Java进阶知识解析.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

day24Java进阶知识解析.docx

《day24Java进阶知识解析.docx》由会员分享,可在线阅读,更多相关《day24Java进阶知识解析.docx(25页珍藏版)》请在冰豆网上搜索。

day24Java进阶知识解析.docx

day24Java进阶知识解析

1批处理文件(bat)

简单的说,批处理的作用就是自动的连续执行多条命令.编写bat处理文件可以使用记事本的方式:

常见批处理文件的命令:

echo表示显示此命令后的字符 

tiltle设置窗口的标题。

echooff表示在此语句后所有运行的命令都不显示命令行本身 

color设置窗体的字体颜色。

@与echooff相象,但它是加在每个命令行的最前面,表示运行时不显示这一行的命令行(只能影响当前行)。

 

pause运行此句会暂停批处理的执行并在屏幕上显示Pressanykeytocontinue...的提示,等待用户按任意键后继续 

rem表示此命令后的字符为解释行(注释),不执行,只是给自己今后参考用的(相当于程序中的注释)或者%注释的内容%

%[1-9]表示参数,参数是指在运行批处理文件时在文件名后加的以空格(或者Tab)分隔的字符串

2对象拷贝

2.1对象的浅拷贝

浅复制(浅克隆)被复制对象的所有变量都含有与原来对象相同的值,而所有的对其他对象的引用仍然只指向原来的对象,换言之,浅复制仅仅复制锁考虑的对象,而不复制它所引用的对象。

publicclassStudentimplementsCloneable{

Stringname;

intage;

Student(Stringname,intage){

this.name=name;

this.age=age;

}

publicObjectclone(){

Objecto=null;

try{

o=super.clone();//Object中的clone()识别出你要复制的哪一个对象

}

catch(CloneNotSupportedExceptione){

System.out.println(e.toString());

}

returno;

}

publicstaticvoidmain(String[]args){

Students1=newStudent("zhang",18);

Students2=(Student)s1.clone();

s2.name="li";

s2.age=20;

System.out.println("name="+s1.name+","+"age="+s1.age);//修改学生2后不影响学生1的值

}

}

2.2对象深拷贝

深复制(深克隆)被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量,那些引用其他对象的变量将指向被复制过的新对象,而不再试原有的那些被引用的对象,换言之,深复制把要复制的对象所引用的对象都复制了一遍。

把对象写到流里的过程是串行化(Serilization)过程,但是在Java程序师圈子里又非常形象地称为“冷冻”或者“腌咸菜(picking)”过程;而把对象从流中读出来的并行化(Deserialization)过程则叫做“解冻”或者“回鲜(depicking)”过程。

应当指出的是,写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面,因此“腌成咸菜”的只是对象的一个拷贝,Java咸菜还可以回鲜。

在Java语言里深复制一个对象,常常可以先使对象实现Serializable接口,然后把对象(实际上只是对象的一个拷贝)写到一个流里(腌成咸菜),再从流里读出来(把咸菜回鲜),便可以重建对象。

publicObjectdeepClone()

{

//将对象写到流里

ByteArrayOutoutStreambo=newByteArrayOutputStream();

ObjectOutputStreamoo=newObjectOutputStream(bo);

oo.writeObject(this);

//从流里读出来

ByteArrayInputStreambi=newByteArrayInputStream(bo.toByteArray());

ObjectInputStreamoi=newObjectInputStream(bi);

return(oi.readObject());

}

1.内存溢出

由于Java具备自动的垃圾回收机制,当我们使用完对象之后,它们会被自动回收,是不是我们在Java程序中不需要再考虑内存管理了吗?

请看如下程序:

classStack{

privateObject[]elements;

//初始化角标

intindex=0;

//默认初始化容量

privateintinitialCapacity=10;

publicStack(){

elements=newObject[initialCapacity];

}

//压栈push

publicvoidpush(Objecte){

ensureCapacity();

elements[index++]=e;

//System.out.println(index);

}

//弹栈pop

publicObjectpop(){

if(index==0){

thrownewRuntimeException("没有元素");

}

returnelements[--index];

}

privatevoidensureCapacity(){

if(index==elements.length){

elements=Arrays.copyOf(elements,index*2+1);

}

}

}

注意:

从栈中弹出的对象不会作为垃圾回收,即使程序不再使用这些对象,因为栈内部继续维护着这些对象.最终可能会导致内存占用的不断增加,程序性能降低.这就是内存泄漏.

改进版本

classStack{

privateObject[]elements;

//初始化角标

intindex=0;

//默认初始化容量

privateintinitialCapacity=10;

publicStack(){

elements=newObject[initialCapacity];

}

//压栈push

publicvoidpush(Objecte){

ensureCapacity();

elements[index++]=e;

//System.out.println(index);

}

//弹栈pop

publicObjectpop(){

if(index==0){

thrownewRuntimeException("没有元素");

}

Objectobj=elements[--index];

elements[index]=null;

returnobj;

}

privatevoidensureCapacity(){

if(index==elements.length){

elements=Arrays.copyOf(elements,index*2+1);

}

}

}

2.设计模式

设计模式(Designpattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。

使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。

2.1.观察者模式

有时又被称为

发布-订阅模式、

模型-视图模式、

源-收听者模式

或从属者模式)

这是软件设计模式的一种。

观察者模式(Observer)完美的将观察者和被观察的对象分离开。

此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。

这通常透过呼叫各观察者所提供的方法来实现。

此种模式通常被用来实作事件处理系统。

有多个观察者时,不可以依赖特定的通知次序。

Swing大量使用观察者模式,许多GUI框架也是如此。

气象站:

publicclassWeatherStation{

privateStringweather;

String[]weathers={"下雨","下雪","下冰雹","出太阳"};

staticListlist=newArrayList();

Randomrandom=newRandom();

publicvoidstartWork(){

newThread(){

@Override

publicvoidrun(){

while(true){

updateWeather();

try{

Thread.sleep(random.nextInt(1000)+500);

}catch(InterruptedExceptione){

e.printStackTrace();

}

}

}

}.start();

}

publicvoidupdateWeather(){

weather=weathers[random.nextInt(4)];

System.out.println("天气:

"+weather);

}

publicStringgetWeather(){

returnweather;

}

人:

publicclassPersonimplementsBookWeather{

Stringname;

publicPerson(Stringname){

this.name=name;

}

privateWeatherStationstation;

publicPerson(Stringname,WeatherStationstation){

this(name);

this.station=station;

}

//下雨","下雪","下冰雹","出太阳"

@Override

publicvoidnotifyWeather(){

Stringweather=station.getWeather();

if("下雨".equals(weather)){

System.out.println(name+"打着雨伞上班");

}elseif("下雪".equals(weather)){

System.out.println(name+"溜冰上班");

}elseif("下冰雹".equals(weather)){

System.out.println(name+"带着头盔上班");

}elseif("出太阳".equals(weather)){

System.out.println(name+"嗮着太阳上班");

}

}

}

测试类:

publicclassTest{

publicstaticvoidmain(String[]args)throwsInterruptedException{

WeatherStationstation=newWeatherStation();

station.startWork();

Personp1=newPerson("小明",station);

while(true){

p1.notifyWeather();

Thread.sleep(2000);

}

}

问题:

天气变化两三次,小明才知道一次。

解决方案:

packagecn.itcast.test;

importjava.util.List;

importjava.util.ArrayList;

importjava.util.Random;

publicclassWeatherStation{

privateStringweather;

String[]weathers={"下雨","下雪","下冰雹","出太阳"};

privatestaticListlist=newArrayList();

Randomrandom=newRandom();

publicvoidaddListaner(BookWeathere){

list.add(e);

}

publicvoidstartWork(){

newThread(){

@Override

publicvoidrun(){

while(true){

updateWeather();

try{

Thread.sleep(random.nextInt(1000)+500);

}catch(InterruptedExceptione){

e.printStackTrace();

}

}

}

}.start();

}

publicvoidupdateWeather(){

weather=weathers[random.nextInt(4)];

System.out.println("天气:

"+weather);

for(BookWeatheritem:

list){

item.notifyWeather(weather);

}

}

publicStringgetWeather(){

returnweather;

}

人:

publicclassPersonimplementsBookWeather{

Stringname;

publicPerson(Stringname){

this.name=name;

}

privateWeatherStationstation;

publicPerson(Stringname,WeatherStationstation){

this(name);

this.station=station;

}

//下雨","下雪","下冰雹","出太阳"

@Override

publicvoidnotifyWeather(Stringweather){

if("下雨".equals(weather)){

System.out.println(name+"打着雨伞上班");

}elseif("下雪".equals(weather)){

System.out.println(name+"溜冰上班");

}elseif("下冰雹".equals(weather)){

System.out.println(name+"带着头盔上班");

}elseif("出太阳".equals(weather)){

System.out.println(name+"嗮着太阳上班");

}

}

}

接口:

publicinterfaceBookWeather{

publicvoidnotifyWeather(Stringweather);

}

 

publicclassTest{

publicstaticvoidmain(String[]args)throwsInterruptedException{

WeatherStationstation=newWeatherStation();

station.startWork();

Personp1=newPerson("小明");

Personp2=newPerson("小红");

Personp3=newPerson("小青");

station.addListaner(p1);

station.addListaner(p2);

station.addListaner(p3);

}

}

 

2.2.单例

Singleton

是指只能拥有一个实例的类就是单例类。

私有构造方法。

获取方式

通过公共的静态方法创建单一的实例。

两种模式

懒汉模式–通常被称为延迟加载。

注意存在线程安全问题.

饿汉模式

懒汉式的单例模式线程安全问题的解决方案:

classSingle{

//声明本类的一个私有的成员变量

privatestaticSinglesingle;

//第一步:

私有化构造方法

privateSingle(){

}

//第三步:

提供一个公共的方法获取该类的实例对象

publicstaticSinglegetInstance(){

if(single==null){

synchronized(single){

if(single==null){

single=newSingle();

}

}

}

returnsingle;

}

}

3.反射

类字节码文件是在硬盘上存储的,是一个个的.class文件。

我们在new一个对象时,JVM会先把字节码文件的信息读出来放到内存中,第二次用时,就不用在加载了,而是直接使用之前缓存的这个字节码信息。

字节码的信息包括:

类名、声明的方法、声明的字段等信息。

在Java中“万物皆对象”,这些信息当然也需要封装一个对象,这就是Class类、Method类、Field类。

通过Class类、Method类、Field类等等类可以得到这个类型的一些信息,甚至可以不用new关键字就创建一个实例,可以执行一个对象中的方法,设置或获取字段的值,这就是反射技术。

3.1.Class类

1.1.1.获取Class对象的三种方式

Java中有一个Class类用于代表某一个类的字节码。

Java提供了三种方式获取类的字节码

forName()。

forName方法用于加载某个类的字节码到内存中,并使用class对象进行封装

类名.class

对象.getClass()

/**

*加载类的字节码的3种方式

*@throwsException

**/

publicvoidtest1()throwsException{

//方式一

Classclazz1=Class.forName("cn.itcast.gz.reflect.Person");

//方式二

Classclazz2=Person.class;

//方式三

Personp1=newPerson();

Classclazz3=p1.getClass();

}

1.1.2.通过Class类获取类型的一些信息

1.getName()类的名称(全名,全限定名)

2getSimpleName()类的的简单名称(不带包名)

3.getModifiers();类的的修饰符

4.创建对象

无参数构造创建对象

newInstance()

5.获取指定参数的构造器对象,并可以使用Constructor对象创建一个实例

ConstructorgetConstructor(Class

>...parameterTypes)

/**

*通过Class对象获取类的一些信息

*

*@throwsException

**/

privatestaticvoidtest2()throwsException{

Classclazz1=Class.forName("cn.itcast.gz.reflect.Person");

//获取类的名称

Stringname=clazz1.getName();

System.out.println(name);//cn.itcast.gz.reflect.Person

//获取类的简单名称

System.out.println(clazz1.getSimpleName());//Person

//获取类的修饰符

intmodifiers=clazz1.getModifiers();

System.out.println(modifiers);

//构建对象(默认调用无参数构造.)

Objectins=clazz1.newInstance();

Personp=(Person)ins;

System.out.println(p);//cn.itcast.gz.reflect.Person@c17164

//获取指定参数的构造函数

Constructor

>con=clazz1.getConstructor(String.class,int.class);

//使用Constructor创建对象.

Objectp1=con.newInstance("jack",28);

System.out.println(((Person)p1).getName());

}

1.1.3.通过Class类获取类型中的方法的信息

1.获取公共方法包括继承的父类的方法

getMethods()返回一个数组,元素类型是Method

2.获取指定参数的公共方法

getMethod("setName",String.class);

3.获得所有的方法,包括私有

Method[]getDeclaredMethods()

4.获得指定参数的方法,包括私有

MethodgetDeclaredMethod(Stringname,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1