2015年1月15日星期四

内部类-语法篇 - 禅楼望月

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
内部类-语法篇 - 禅楼望月  阅读原文»

作者:禅楼望月(http://www.cnblogs.com/yaoyinglong

1.什么是内部类

简单的说就是在一个类、接口或者方法的内部创建一类。这样理解的话创建内部类的方法就很明确了。

package com.gissky.innerClass;

public class Path {
public class Start{
public Start(String start){
this.start=start;
}
private String start;
public String getStart() {
return start;
}
}
public class End{
public End(String end){
this.end=end;
}
private String end;
public String getEnd() {
return end;
}
}
}

2.内部类的实例化

2.1 在外部类的非静态方法内部实例化,这个很简单,和我们平时做的一样。

public Start start(String start){
return new Start(start);
}
public End end(String end){
return new End(end);
}

2.2 在外部类的非静态方法外部的任意位置创建内部类对象的时候,必须具体指明这个对象的类型,即:OuterClassName.InnerClassName,并且必须在有外部类对象的前提下进行,使用类似:外围类对象.new 内部类();这样的语法。

public static void main(String[] args){
Path path
=new Path();
Path.Start start
=path.new Start("my home");
Path.End end
=path.new End("fu zhou");
path.Go(start, end);
}

3. 内部类有一个指向外部类的对象的引用

内部类拥有其外部类的所有元素的访问权。这是如何做到的呢?修改一下上面的程序:

public class Path {
private double startTime;
private double endTime;
public class Start{
public Start(String start){
startTime
=new Date().getTime();
this.start=start;
}
private String start;
public String getStart() {
return start;
}
}
public class End{
public End(String end){
this.end=end;
endTime
=new Date().getTime();
}
private String end;
public String getEnd() {
return end;
}
}

public void Go(Start start,End end){
System.out.println(
"start to end");
System.out.println(endTime
-startTime);
}
public Start start(String start){
return new Start(start);
}
public End end(String end){
return new End(end);
}
}

这是编译器已经帮我们生成了3个.class文件:

image

其两个便是编译器生成的内部类的.class文件,奇怪的是它们是以其外部类开头再加上$和自己类的名字。我们用javap反编译工具查看一下:

image

由此我们便可以知道,内部类中访问外部类的成员变量是通过一个调用外部类的一个静态方法进行的,该静态方法须传入一个外围类的引用。

到这里应该明白2.2中提到的"在外部类的非静态方法外部的任意位置创建内部类对象的时候,必须具体指明这个对象的类型,即:OuterClassName.InnerClassName,并且必须在有外部类对象的前提下进行"的原因了吧。那是因为,内部类要连接到创建它的外部类对象上。

这样做不是存在?div style="border-bottom:1px solid #aaa;margin-bottom:25px">ORACLE清理、截断监听日志文件(listener.log) - 潇湘隐者  阅读原文»

在ORACLE数据库中,如果不对监听日志文件(listener.log)进行截断,那么监听日志文件(listener.log)会变得越来越大,想必不少人听说过关于"LISTENER.LOG日志大小不能超过2GB,超过会导致LISTENER监听器无法处理新的连接",当然这个不是真理,不会绝对出现,只是发生在老旧的32bit Linux或Unix系统下面,真实的原因是一些32bit OS自带的文件系统不支持2GB以上的文件,导致监听服务进程(tnslsnr)append write日志文件出错。

那么是否不需要对监听日志文件进行截断维护呢? 答案是否定的。当然要对监听日志文件(listener.log)进行定期清理,如果不定期清理,会遇到下面一些麻烦:

1:监听日志文件(listener.log)变得越来越大,占用额外的存储空间。(当然现在存储白菜价,不差那几G的空间。但是我们还是要本着工匠情怀,精益求精)

2:监听日志文件(listener.log)变得太大会带来一些问题:LISTENER.LOG日志大小不能超过2GB,超过会导致LISTENER监听器无法处理新的连接。

3:监听日志文件(listener.log)变得太大,给写入、查看带来的一些性能问题、麻烦。

也有人说是监听服务进程一般使用标准C函数Write写出到Listener.log,listener.log文件时使用的是O_WRONLY|O_CREAT|O_APPEND,O_APPEND即追加到文件的尾端,一般来说追加写方式不会因为文件越大写地越慢。撇开这个不谈,在一个很大的监听日志文件(listener.log)查找某一天或某一个错误,这个确实会带来一些性能问题。查找起来也相当麻烦。

所以应该定期对监听日志文件(listener.log)进行清理,另外一种说法叫截断日志文件。关于截断监听日志,要注意一些问题。初学ORACLE的时候遇到一个错误的截断监听日志的,下面演示一下

[oracle@DB-Server log]$ mv listener.log listener.log.20150114 [oracle@DB-Server log]$ cp /dev/null listener.log [oracle@DB-Server log]$ more listener.log

如上所示,这样截断监听日志(listener.log)后,监听服务进程(tnslsnr)并不会将新的监听信息写入listener.log,而是继续写入listener.log.20150114

[oracle@DB-Server log]$ tail listener.log.2015011415-JAN-2015 22:40:01 * service_update * EPPS * 015-JAN-2015 22:47:59 * service_update * EPPS * 015-JAN-2015 22:58:00 * service_update * EPPS * 015-JAN-2015 23:08:00 * service_update * EPPS * 015-JAN-2015 23:18:01 * service_update * EPPS * 015-JAN-2015 23:28:01 * service_update * EPPS * 015-JAN-2015 23:38:02 * service_update * EPPS * 015-JAN-2015 23:41:02 * service_update * EPPS * 015-JAN-2015 23:50:26 * ping * 015-JAN-2015 23:51:03 * service_update * EPPS * 0[oracle@DB-Server log]$ tail listener.log.2015011415-JAN-2015 23:18:01 * service_update * EPPS * 015-JAN-2015 23:28:01 * service_update * EPPS * 015-JAN-2015 23:38:02 * service_update * EPPS * 015-JAN-2015 23:41:02 * service_update * EPPS * 015-JAN-2015 23:50:26 * ping * 015-JAN-2015 23:51:03 * service_update * EPPS * 015-JAN-2015 23:57:40 * ping * 015-JAN-2015 23:57:41 * ping * 015-JAN-2015 23:57:42 * ping * 015-JAN-2015 23:57:43 * ping * 0[oracle@DB-Server log]$ more listener.log[oracle@DB-Server log]$

clip_image001

规范正确的流程应该这么处理:

Step 1:首先停止监听服务进程(tnslsnr)记录日志。

[oracle@DB-Server log]$ lsnrctl set log_status off; LSNRCTL for Linux: Version 10.2.0.4.0 - Production on 16-JAN-2015 00:02:59 Copyright (c) 1991, 2007, Oracle. All rights reserved. Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.9.15)(PORT=1521)))LISTENER parameter "log_status" set to OFFThe command completed successfully

Step 2:将监听日志文件(listener.log)复制一份,以listener.log.yyyymmdd格式命名

[oracle@DB-Server log]$ cp listener.log listener.log.20150114

Step 3:将监听日志文件(listener.log)清空。清空文件的方法有很多

3.1 echo "" > filename

3.2 cp /dev/null 或 echo /dev/null > filename

Step 4:开启监听服务进程(tnslsnr)记录日志

[oracle@DB-Server log]$ lsnrctl set log_status on;

当然也可以移走监听日志文件(listener.log),数据库实例会自动创建一个listener.log文件。

% lsnrctl set log_status off % mv listener.log listener.yyyymmdd % lsnrctl set log_status on

当然这些操作应该通过shell脚本来处理,然后结合crontab作业定期清理、截断监听日志文件。例如网上的一个清理、截断监听日志文件的shell脚本。

没有评论:

发表评论