这段java零基础入门书籍代码哪里出错了呢?

2918 条评论分享收藏感谢收起赞同 71 条评论分享收藏感谢收起1.jps可以理解成进程的ps,也就是罗列出所有的正在运行的Java进程(这里不截图了);
2.jstat 一个极强的一个VM监控工具;jstat -gcutil
pid 可以查看对应该id进程的gc所有状况,如下图:
下面解释一下各个字母表示的意思:
s0:如果了解JVM的童鞋,很清楚s0就是Java堆内存里的新生代的survivor space0的简称,所有该值指的是新生代s0的已使用的百分比
s1:如同上面,s1自然而然的就是Java堆内存里新生代的survivor space1的简称,所有该值指的是新生代s1的已使用的百分比
E: E是新生代Eden的简称,这里表示eden区域使用的百分比
O:自然而然的就是oldspace使用耳朵区域,但这里并不是指的是老年代;
p :premspace的简称,指的的老年代使用的百分比;
YGC:新生代的GC次数,也就是MiniorGC的次数,
YCGT:新生代GC所用的时间;
FGC:老年代的GC次数;
FGCT:老年代的GC次数的时间
GCT:垃圾回收的总时间
2.jstat -class 显示加载class的数量
Loaded表示已经加载的class类的数量,Bytes表示Loaded多少字节,unloaded表示没有加载的class,Bytes表示unloaded多少字节
Time表示加载时间
3.jmap pid
heap,以二进制输出成文本。使用方法 jmap -histo pid。如果连用 SHELL jmap -histo pid&a.log可以将其保存到文本中去(windows下也可以使用),在一段时间后,使用文本对比工具,可以对比出GC回收了哪些对象。(这里就不截图了)
基本上借用上面三种工具很快就能定位到代码哪里出问题了,或者哪里需要优化;
内容:using Susing System.Collections.Gusing System.ComponentMusing System.Dusing...
void strcat(char *a,char *b)
while(*(a+i)!='\0')
#include &stdio.h&#include &stdlib.h&#include &time.h&#inc...
没有更多推荐了,16:02 提问
这段java代码如何优雅的实现?
for(AbstractResponse resp : responseList) {
if (resp instanceof AResponse) {
AResponse areponse = (AResponse)
}else if (resp instanceof BResponse) {
BResponse breponse = (BResponse)
}else if (resp instanceof CResponse) {
CResponse creponse = (CResponse)
不好意思,刚才写错了,修改了一下
按赞数排序
要优雅,有两个办法,一个是
AbstractResponse定义一个方法,它的派生类重写这个方法。
你循环直接调用,它会调用对应的派生类重写的不同方法
另一个,你不能或者不想改变AbstractResponse的代码。
那么可以使用泛型+策略模式,为每个类型编写一个策略实现类,在你的for里面,调用泛型方法,那么它会自动找策略类。
这代码有问题啊,for(AResponse resp : responseList) 这个地方初期化的resp一定是AResponse类,不可能走到else if里面的后面的代码都是多余的
for(AResponse resp : responseList)
多谢关注,这个写错了,修改了一下
已经很优雅了
既然AResponse,BResponse,CResponse都是继承AbstractResponse,那直接在AbstractResponse 定义一个方法,让AResponse,BResponse,CResponse都实现这个方法,那在上面的程序调用时就不需要判断是否是AResponse,BResponse,CResponse了。
abstract class AbstractResponse
abstract void print();
class AResponse extends AbstractResponse
public void print()
System.out.println("AResponse");
class BResponse extends AbstractResponse
public void print()
System.out.println("BResponse");
class CResponse extends AbstractResponse
public void print()
System.out.println("CResponse");
for(AbstractResponse resp : responseList) {
resp.print();
应该就是java多态的表现方式啦!
Class&?& cClass = resp.getClass();
Object temp = cClass.newInstance();
直接使用java的反射机制 你可以试试效果
List&Object& abc = new ArrayList&Object&();
Map&String,Object& d = new HashMap&String,Object&();
d.put("abc", "abc");
abc.add(d);
Map&String,Object& e = new Hashtable&String,Object&();
e.put("abc", "abc");
abc.add(e);
for(Object tempMap :abc){
Class&?& cClass = tempMap.getClass();
Object temp = cClass.newInstance();
temp = tempM
System.out.println("This is " + cClass);
System.out.println(temp);
这种结构已经很好了,易读。
如果想减少代码量,也是在 if else 分支特别多的情况下才有用,就这几个分支就不用考虑了。
如果一定要考虑,可以试试 for 循环。但前提是各分支中的处理要基本上相同,可以抽象出来。否则,也无法实现!
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐你的java/c/c++程序崩溃了?揭秘段错误(Segmentation fault)(3)
我的图书馆
你的java/c/c++程序崩溃了?揭秘段错误(Segmentation fault)(3)
接上两篇:你的C/C++程序为何没法运行?揭秘Segmentation fault (1)&你的C/C++程序为何没法运行?揭秘Segmentation fault (2)写到这里,越跟,越发现真的是内核上很白,非1般的白。&但是既然是研究,就定住心,把段毛病弄到清楚明白。本篇将作为终篇,来结束这个系列,也算是对段毛病和程序调试、寻觅崩溃缘由(通常不会给你那末完善的stackstrace和人性化的毛病提示)的再深入。本篇使用到的工具或命令:dmesgstracegdblinux 内核3.10源码情形再现上两篇围绕着1个这样的问题进行展开:&char&**&&p =&NULL;&&*p = (char&*)malloc(sizeof(char));问题代码为了本篇的可读性,围绕上述问题编织问题代码:#include "stdio.h"&#include "string.h"&#include "stdlib.h"&int&main(int&argc,char** args) {&char&* p = NULL; *p =&0x0; }段毛病找出问题第1步 strace 查信号描写上篇已介绍了gbd+coredump的方法来找到出现段毛病的代码,本篇直接上strace:strace&-i&-x&-o&segfault.txt&./segfault.o得到以下信息:&可以知道:1.毛病信号:SIGSEGV&3.毛病码:SEGV_MAPERR&3.毛病内存地址:0x0&4.逻辑地址0x400507处出错.可以猜想:程序中有空指针访问试图向0x0写入而引发段毛病.第2步 dmesg 查毛病现场上dmesg:dmesg得到:&可知:1.毛病类型:segfault ,即段毛病(Segmentation Fault).&2.出错时ip:0x400507&3.毛病号:6,即110第3步 搜集已知结论这里&毛病号和ip&是关键,毛病号对比下面:/* * Page fault error code bits: * * bit&0&==&0:&no&page found&1: protection fault * bit&1&==&0:&read&1:&write&&* bit&2&==&0: kernel-mode&&1: user-mode&&* bit&3&==&1:&use&of reserved bit detected * bit&4&==&1: fault was an instruction fetch&*/&/*enum&x86_pf_error_code { PF_PROT =&1&&&&0, PF_WRITE =&1&&&&1, PF_USER =&1&&&&2, PF_RSVD =&1&&&&3, PF_INSTR =&1&&&&4, };*/对比后可知:毛病号6 = 110 = (PF_USER | PF_WIRTE | 0).&即“用户态”、“写入型页毛病 ”、“没有与指定的地址相对应的页”.上面的信息与我们最初的推断吻合.现在,对目前已知结论进行概括以下:1.毛病类型:segfualt ,即段毛病(Segmentation Fault).2.出错时ip:0x4005073.毛病号:6,即1104.毛病码:SEGV_MAPERR 即地址没有映照到对象.5.毛病缘由:对0x0进行写操作引发了段毛病,缘由是0x0没有与之对应的页或叫映照.第4步 根据结论找到出错代码上gdb:gdb ./segfault.o根据结论中的ip = 0x400507立即得到:明显,这验证了我们的结论:我们试图将值0x0写入地址0x0从而引发写入未映照的地址的段毛病.并且我们找到了毛病的代码stack.c的第9行:查根溯源明显,我们不满足于此,为何访问了0x0会造成这个毛病从而让程序崩溃?第2篇已说了进程虚拟地址空间的问题,事实上我们进行写入操作的时候,会引发虚拟地址到物理地址的映照,由于你终究要将数据(本篇是0x0,注意和我们的地址0x0辨别)写入到物理内存中。0x0是个逻辑地址,linux按页式管理内存映照,0x0不会对应任何页,那末内存中就不会有主页,所以对其进行写入就会引发1个缺页中断,这1部份由linux内存映照管理模块(memory mapping,缩写mm)处理。缺页毛病处理1. __do_page_fault缺页落后入__do_page_fault流程,注意,这里为了尽可能减少篇幅,删去了源代码的1些注释,而与我们有关的命中代码都做了注释:&static&void&__kprobes __do_page_fault(struct&pt_regs *regs,&unsigned&long&error_code.) {&struct&vm_area_struct *&structtask_struct *&unsigned&long&&struct&mm_struct *&int&&int&write = error_code & PF_WRITE;&unsigned&int&flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | (write ? FAULT_FLAG_WRITE :&0); tsk = mm = tsk-&&&address = read_cr2();&if&(kmemcheck_active(regs)) kmemcheck_hide(regs); prefetchw(&mm-&mmap_sem);&if(unlikely(kmmio_fault(regs, address)))&return;&if&(unlikely(fault_in_kernel_space(address))) {&&&return; }&&&retry: down_read(&mm-&mmap_sem); }&else&{ might_sleep(); } vma = find_vma(mm, address);&if&(unlikely(!vma)) {&&bad_area(regs, error_code, address);&&return; }&&&}2. bad_area其中的1个关键调用bad_area(regs, error_code, address);static&noinline&void&bad_area(struct&pt_regs *regs,&unsigned&long&error_code,&unsigned&long&address) {&__bad_area(regs, error_code, address, SEGV_MAPERR); }可以明确我们结论中的SEGV_MAPERR的出处.这个类型就是没法映照到对象的意思!看下面strace得到的东西,其中&si_code=SEGV_MAPERR.---&&,&,&&---&+++&&&&&&+++最后会来到这里:static&void&__bad_area_nosemaphore(struct&pt_regs *regs,&unsigned&long&error_code,&unsigned&long&address,&int&si_code) {&struct&task_struct *tsk =&&if&(error_code & PF_USER) {&&local_irq_enable();&if&(address &= TASK_SIZE) error_code |= PF_PROT;&&if&(likely(show_unhandled_signals)) show_signal_msg(regs, error_code, address, tsk); tsk-&thread.cr2 = tsk-&thread.error_code = error_ tsk-&thread.trap_nr = X86_TRAP_PF;&force_sig_info_fault(SIGSEGV, si_code, address, tsk,&0);&return; }&&}注意上面的代码的两个关键调用:show_signal_msg&&force_sig_info_fault&3. show_signal_msg&staticinline&void&show_signal_msg(struct&pt_regs *regs,&unsigned&long&error_code,&unsigned&long&address,&struct&task_struct *tsk) {&&&printk("%s%s[%d]: segfault at %lx ip %p sp %p error %lx", task_pid_nr(tsk) &&1&? KERN_INFO : KERN_EMERG, tsk-&comm, task_pid_nr(tsk), address, (void&*)regs-&ip, (void&*)regs-&sp, error_code); print_vma_addr(KERN_CONT&" in ", regs-&ip); printk(KERN_CONT&" "); }其中,打印段毛病的信息的代码,就是我们使用dmesg得到的东西.可以对照下我们的段毛病的图:&4. force_sig_info_fault最后就是发送信号了。static&void&force_sig_info_fault(int&si_signo,&int&si_code,&unsigned&long&address,&struct&task_struct *tsk,&int&fault) {&unsigned&lsb =&0; siginfo_ info.si_signo = si_ info.si_errno =&0; info.si_code = si_ info.si_addr = (void&__user *)&if&(fault & VM_FAULT_HWPOISON_LARGE) lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault));&if&(fault & VM_FAULT_HWPOISON) lsb = PAGE_SHIFT; info.si_addr_lsb =&&force_sig_info(si_signo, &info, tsk); }force_sig_info:int&force_sig_info(int&sig,&struct&siginfo *info,&struct&task_struct *t) {&unsigned&long&int&&intret, blocked,&struct&k_sigaction * spin_lock_irqsave(&t-&sighand-&siglock, flags);&&action = &t-&sighand-&action[sig-1];&&&if(action-&sa.sa_handler == SIG_DFL)&&t-&signal-&flags &= ~SIGNAL_UNKILLABLE;&&ret = specific_send_sig_info(sig, info, t); spin_unlock_irqrestore(&t-&sighand-&siglock, flags);&return& }上面的代码告知我们,信号的处理程序如何被指定的,那末关于段毛病的信号SEGSIGV默许就是core dump.5. core dump到此,我们已可以拿到core dump,那末第2篇中找到引发段毛病的代码的方法就能够用了,这也是推荐的做法:gdb ./segfault.o&core.36054是否是立便可知stack.c第9行的代码*p = 0x0是罪魁罪魁了呢?结语到此,全部段毛病的探索就结束了,希望读者和我1样不枉此行。列出几种常见段毛病缘由:1.数组越界int&a[10] = {0,1};&printf("%d",a[10000]);2.零指针或空指针&char&* p = NULL; *p =&0x0;3.悬浮指针如果指针p悬浮,它指向的地址有可能能用,也有可能不能,你不知道那块地址甚么时候被写入,甚么时候被保护(mprotect).&如果被保护为可读,你写就出现段毛病!4.访问权限,非法访问参见3.5.多线程对同享指针变量操作不但c/c++,android中、java程序中有可能也会出现jvm崩溃哦,那检查下多线程的同享变量吧!----分隔线----------------------------注栏目热点
喜欢该文的人也喜欢这段代码报错的原因 - ITeye问答
import java.awt.*;
import javax.swing.*;
public class Lab_08 extends JFrame{
public static void main(String args[]){
&&& JFrame fra=new JFrame("主窗口");
&&& fra.setSize(100,200);
&&& Container c=fra.getContentPane();
&&& JLabel label=new JLabel("显示文件的标签");
&&&&&&& label.setToolTipText("这是标签对象");
&&&&&&& fra.add(c);
&&&&&&& c.add(label);
&&&&&&& fra.setVisible(true);
Exception in thread "main" java.lang.IllegalArgumentException: adding container's parent to itself
at java.awt.Container.addImpl(Container.java:1056)
at java.awt.Container.add(Container.java:974)
at javax.swing.JFrame.addImpl(JFrame.java:556)
at java.awt.Container.add(Container.java:377)
at Lab_08.main(Lab_08.java:10)
多了这行了,不能把自己的容器放到自己里.....
fra.add(c);
把这行去 掉,
import java.awt.*;
import javax.swing.*;
public class Lab_08 extends JFrame{
public static void main(String args[]){
JFrame fra=new JFrame("主窗口");
fra.setSize(100,200);
Container c=fra.getContentPane();
JLabel label=new JLabel("显示文件的标签");
label.setToolTipText("这是标签对象");
//fra.add(c);
c.add(label);
fra.setVisible(true);
已解决问题
未解决问题

我要回帖

更多关于 java经典编程300例 的文章

 

随机推荐