精华内容
下载资源
问答
  • java一个对象的一生

    2019-09-25 22:16:17
    一个对象的一生:我是一个普通的Java对象,我出生在Eden区,在Eden区我还看到和我长的很像的小兄弟,我们在Eden区中玩了挺长时间。有一天Eden区中的人实在是太多了,我就被迫去了Survivor区的“From”区,自从去了...

    一个对象的一生:我是一个普通的Java对象,我出生在Eden区,在Eden区我还看到和我长的很像的小兄弟,我们在Eden区中玩了挺长时间。有一天Eden区中的人实在是太多了,我就被迫去了Survivor区的“From”区,自从去了Survivor区,我就开始漂了,有时候在Survivor的“From”区,有时候在Survivor的“To”区,居无定所。直到我18岁的时候,爸爸说我成人了,该去社会上闯闯了。于是我就去了年老代那边,年老代里,人很多,并且年龄都挺大的,我在这里也认识了很多人。在年老代里,我生活了20年(每次GC加一岁),然后被回收。

    展开全文
  • 对象的一生像往常一样,早上10点到了公司,赵小八打开电脑收到了PM前一天晚上发来的推荐系统新需求,内心一万只草泥马飘过,思索了半天,打开IDEA开始了“愉快的”new对象之旅。垃圾回收...

    “对象”的一生

    像往常一样,早上10点到了公司,赵小八打开电脑收到了PM前一天晚上发来的推荐系统新需求,内心一万只草泥马飘过,思索了半天,打开IDEA开始了“愉快的”new对象之旅。

    垃圾回收器老哥:你这样疯狂的嚯嚯对象,有考虑过我的感受吗?

    赵小八:你谁啊?我new对象干你啥事?

    垃圾回收器老哥:年轻人火气别这么大,既然你这么说那请耗子尾汁。

    赵小八:呵,你哥我是被吓大的

    垃圾回收器老哥:年轻人不讲武德...

    没两天,小八翘着尾巴给PM说,功能上线了,刚没一会儿PM骂骂咧咧的找来了,这tm为啥有时候能出来内容有时候出不来啊,小八菊花一紧赶紧查起了问题,先搂监控接口平均耗时从200ms涨到了300ms,小八心想,我不过就多new了几个对象,怎么tm的影响会这么大,同时DBA同学反馈资源监控正常,看来只能搂业务日志看看了,可是业务日志也并没有什么问题,难道GC有问题?果不其然,GC日志像疯了一样的刷日志。小八赶紧让运维紧急回滚线上代码并dump了一份GC日志分析了起来。

    现场代码复原

    上面这段代码是一个简化版的用户推荐系统,真实情况下加载需要加载的物料除机器学习物料、商业物料外,还有其他各种例如:运营物料、曝光物料、关系物料等等。

    当一个真实用户请求过来之后,上面提到的这些物料就需要全部被加载进来。对象首先从新生代中被创建出来,接着经过一段时间GC后,最后存活下来的对象成功晋级到老年代,那么对象是在什么情况下成功晋级到老年代的呢?

    case1:对象经历15次GC

    1. 小八疯狂的new对象,此时新创建的都被分配到Eden区,如下图:

    1. 小八继续疯狂new对象,直到jvm老哥的Eden区放不下更多的对象了,于是触发了一次youngGC,通过这次youngGC之后,只有Context1对象被回收,剩余存活对象进入到了Survivor1里面,如下图:

    1. 第一次youngGC结束后,小八又开始了new对象的神操作

    1. 没一会儿,jvm又开始了youngGC,此时Eden区和Survivor1里面的存活对象全部移入到Survivor2中,剩余垃圾对象被回收。

    1. 就这样反反复复经历了15次youngGC的折腾,还没有被垃圾回收掉的对象最终进入了Old区

    case2:动态年龄判断

    1. 小八疯狂的new对象

    1. 小八继续疯狂new对象,直到jvm老哥的Enden区放不下更对的对象了,于是触发了一次youngGC

    经过此次youngGC后,剩余存活对象内存占用大小超过了survivor1区大小的50%,比如:survivor1区大小为50M,而进入到survivor1区的存活对象大小为30M,此时会将当前存活时间最久的对象直接晋升到老年代(存活时间:经历过GC次数最多的对象),此时Context2对象和Context3对象进入到老年代

    case3:空间担保机制

    小八上线的用户推荐系统,JVM内存的划分情况为:整个堆大小为5G,其中老年代2.5G,新生代2.5G,其中新生代中Eden区:Survivor区=8:2,即Eden区大小为2G,两个Survivor区大小各为250M。

    在晚高峰的时候一下子涌入1000人查看推荐列表,一个用户消耗的JVM内存达到了500kb,那么在一秒内就消耗了500M,那么就意味着4秒钟就会产生一次youngGC,假设每次GC后剩余的存活对象为300M,由于300M大小的存活对象无法在survivor区中存放下,此时就触发了空间担保机制。

    1. 小八疯狂的new对象

    1. 直到发生第一次youngGC,但是一次youngGC后剩余的存活的对象大小Survivor区无法容纳下,此时所有存活对象会直接进入到Old区

    在新生代没有足够的内存存储新产生的对象时,老年代会判断自己的区域剩余的内存空间是否能够放得下历代youngGC后剩余存活对象(假设历代youngGC剩余存活对象大小为300M),假设此时老年代还有1G大小的可用内存,那么此次youngGC后剩余的存活对象将直接进入到老年代;假设此时老年代剩余可用内存大小为200M,那么就会触发一次OldGC,OldGC完成后产生的空闲空间大于300M,此时会将新生代的存活对象放入老年代,如果OldGC后剩余的空闲空间小于300M,那么不好意思,就会抛出OOM了。

    一图总结Java对象流转情况

    上图便是整个Java对象一生经历的流程,流程图相对比较复杂一点,从上往下对照前面讲到的三种情况,相信还是比较容易理解的。

    当然图中没有画图新生代触发OOM的情况,可以试想一下Eden区在什么时候会触发OOM?答案在下篇文章给出。

    总结

    通过一个实际线上案例,讲述了Java对象在不同情况下在JVM中经历的一生。通过本文大家可以尝试将该流程套用到自己公司的项目里面,来分析自己负责的项目是否有类似的问题,或者通过本篇文章来尝试优化自己的项目。另外本文的内容可能会有某些地方讲解的不合适,欢迎有问题的朋友和我私聊探讨。

    在上篇文章中留了一个问卷调查,结论如下:总投票人数7人,其中最想了解的技术是SpringCloud,最喜欢的分享方式是图文结合。虽然投票人数比较少,但我相信投票的真实性,后续我会以这个结论为导向,分享更多实用的内容给大家。

    打个小广告,年后大家有换个工作氛围的朋友或者身边有想法的朋友,快手研发、运维、产品、运营全部岗位都有你想要的坑位,各种新业务发展速度快,机会多多,面试流程反馈速度超快,欢迎朋友们自荐或者推荐朋友来一起做点有意义的事。

    特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:
    
    
    
    长按订阅更多精彩▼
    
    如有收获,点个在看,诚挚感谢
    
    展开全文
  • Java线程的一生

    2020-06-04 17:20:09
    所谓"万物皆对象",在Java中,Thread类就是对线程抽象。 那么首先,在Java中是如何启动线程呢?有2种方法:①继承Thread类;②实现Runnable接口; jdk1.5引入了第三种方式:实现Callable接口,但Callable启动...

    Java中的线程

    线程的新建启动

    Java程序在运行时,除业务所用的线程外,还有后台守护线程,用于JVM执行资源关闭垃圾回收监听机制等等。所以Java中的程序天生便是多线程的。
    本章,将讲述Java中线程的使用。所谓"万物皆对象",在Java中,Thread类就是对线程的抽象。
    那么首先,在Java中是如何启动线程的呢?有2种方法:①继承Thread类;②实现Runnable接口;
    jdk1.5引入了第三种方式:实现Callable接口。

    继承Thread类

    首先编写一个对象,继承Thread类,代表一个线程。重写run()方法,编写该线程具体任务。

    public class NewThread1 extends Thread{
    	@Override
    	public void run() {
            System.out.println("NewThread1 extends Thread run...");
    	}
    }
    

    然后 main方法,初始化对象,调用start()方法,运行线程。

    public class Main{
    	public static void main(String[] args){
       		 NewThread1 newThread1 = new NewThread1();
      	     newThread1.start();
    	}
    }
    

    实现Runnable接口

    首先编写一个对象,实现Runnable接口。重写run()方法,编写需要线程具体执行的任务。

    public class NewThread2 implements Runnable{
    	@Override
    	public void run() {
            System.out.println("NewThread21 implements Runnable run...");
    	}
    }
    

    然后 main方法,初始化上面编写好的需要任务对象,以编写好的任务对象构造一个线程对象,调用start()方法,运行线程。

    public class Main{
    	public static void main(String[] args){
       		 NewThread2 newThread2 = new NewThread2();
      	     new Thread(newThread2).start();
    	}
    }
    

    实现Callable接口

    我们可以看到上述两种方式,启动线程的方法大致方向就是重写run()方法,new一个Thread类或其子类,调用start()方法。
    但Callable的启动线程的方式与众不同。

    1. 它虽然也要重写方法,但重写的不是run(),是call();
    2. Callable的call()方法有泛型返回值,而Runnable与Thread的子类重写的run()方法不能有返回值;
    3. 上述两种方式只需要初始化自身或者自身构造一个Thread类,调用start()即可启动线程,但Callable创建线程需要FutureTask的支持。
    	public class NewCallable implements Callable<Integer>{
    		@Override
    		public Integer call() {
    			System.out.println("NewCallable implements Callable<Integer> call...");   
    	        return 1; 
    		}
    	}
    
    public class Main{
    	public static void main(String[] args){
       		 NewCallable newca = new NewCallable();
       		 //用FutureTask包装Callable
       		 FutureTask<Integer> task = new FutureTask<>(newca);
      	     new Thread(task).start();
    	}
    }
    

    疑惑

    为什么要重写run()方法? 查看Thread源码,无论从注释还是从run()代码都能发现,当线程是Thread的子类时,run()方法并不会做任何操作;而Runnable是一个函数式接口,run()是抽象方法,依赖于实现类。

    public class Thread implements Runnable{
     /* What will be run. */
     private Runnable target;
        /**
         * If this thread was constructed using a separate
         * <code>Runnable</code> run object, then that
         * <code>Runnable</code> object's <code>run</code> method is called;
         * otherwise, this method does nothing and returns.
         * <p>
         * Subclasses of <code>Thread</code> should override this method.
         *
         * @see     #start()
         * @see     #stop()
         * @see     #Thread(ThreadGroup, Runnable, String)
         */
        @Override
        public void run() {
            if (target != null) {
                target.run();
            }
        }
        
    }
    

    使用start()启动线程?
    new一个Thread,此时只是单纯的在JVM创建一个Thread对象,并没有与实际操作系统进程中的线程挂钩,当调用start()方法,运行start0()这个本地方法,才与线程真正挂钩。

      /**
         * Causes this thread to begin execution; the Java Virtual Machine
         * calls the <code>run</code> method of this thread.
         * <p>
         * The result is that two threads are running concurrently: the
         * current thread (which returns from the call to the
         * <code>start</code> method) and the other thread (which executes its
         * <code>run</code> method).
         * <p>
         * It is never legal to start a thread more than once.
         * In particular, a thread may not be restarted once it has completed
         * execution.
         *
         * @exception  IllegalThreadStateException  if the thread was already
         *               started.
         * @see        #run()
         * @see        #stop()
         */
        public synchronized void start() {
            /**
             * This method is not invoked for the main method thread or "system"
             * group threads created/set up by the VM. Any new functionality added
             * to this method in the future may have to also be added to the VM.
             *
             * A zero status value corresponds to state "NEW".
             */
            if (threadStatus != 0)
                throw new IllegalThreadStateException();
    
            /* Notify the group that this thread is about to be started
             * so that it can be added to the group's list of threads
             * and the group's unstarted count can be decremented. */
            group.add(this);
    
            boolean started = false;
            try {
                start0();
                started = true;
            } finally {
                try {
                    if (!started) {
                        group.threadStartFailed(this);
                    }
                } catch (Throwable ignore) {
                    /* do nothing. If start0 threw a Throwable then
                      it will be passed up the call stack */
                }
            }
        }
       
       private native void start0();
    

    此时,有一个问题:start()能否多次调用? 答案是不能的,根据上述源码可以看到threadStatus != 0的异常抛出。当线程调用一次后,当前threadStatus也就不再等于0,再次调用就会抛出异常。

    Callable与FutureTask
    FutureTask可通过Callable构造。而FutureTask实现RunnableFuture接口;RunnableFuture接口继承Runnable接口,有抽象方法run();根据源码可以看到在FuntureTask中实现的run()方法内调用了call()方法。也就是说,Callable方式的实现,其本质仍是重写run()方法,调用start()启动线程。
    start0()如何使Thread与线程真正挂钩
    threadStatus启动线程后如何变化

    待补充

    public class FutureTask<V> implements RunnableFuture<V> {
        public void run() {
            if (state != NEW ||
                !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                             null, Thread.currentThread()))
                return;
            try {
                Callable<V> c = callable;
                if (c != null && state == NEW) {
                    V result;
                    boolean ran;
                    try {
                        result = c.call();
                        ran = true;
                    } catch (Throwable ex) {
                        result = null;
                        ran = false;
                        setException(ex);
                    }
                    if (ran)
                        set(result);
                }
            } finally {
                // runner must be non-null until state is settled to
                // prevent concurrent calls to run()
                runner = null;
                // state must be re-read after nulling runner to prevent
                // leaked interrupts
                int s = state;
                if (s >= INTERRUPTING)
                    handlePossibleCancellationInterrupt(s);
            }
        }
        
    }
    

    线程的结束中止

    讨论完线程的启动,那么,如何结束一个线程?又或者如何中止一个线程?Java中提供了一系列的方法。结束有stop()关闭,destroy(),suspend()挂起,resume();但查看源码能够发现系统给这些结束方法打上了@Deprecated注解,不推荐使用。其原因很简单:如suspend挂起方法,它的调用会将线程挂起,但并不释放该线程占用的资源,这可能引发死锁。stop()终结时会强制结束线程,并不关心线程占用的资源。
    取代结束的是中断机制,interrupt()方法,正常停止线程使用。interrupted()与isInterrupted()判断当前线程是否被中断。

    interrupte()、interrupted()、isInterrupted()

    interrupte()方法的实质是修改线程的中断标志位,只是告诉线程这个地方有人要求中断。这也就是说明jdk线程是协作式,而不是抢占式
    interrupted()、isInterrupted()都是用来判定当前是否要求中断。其区别在于isInterrupted()方法是static方法,同时调用后会修改中断标志位为false。查看源码可以发现interrupted()与isInterrupted()的实质是调用本地方法isInterrupted()。ClearInterrupted入参确定是否重置中断状态,这也就是为什么isInterrupted()会修改中断标志位为false。

        public static boolean interrupted() {
            return currentThread().isInterrupted(true);
        }
        
        public boolean isInterrupted() {
            return isInterrupted(false);
        }
        
        /**
         * Tests if some Thread has been interrupted.  The interrupted state
         * is reset or not based on the value of ClearInterrupted that is
         * passed.
         */
        private native boolean isInterrupted(boolean ClearInterrupted);
    

    守护线程

    守护线程是一种支持型线程,用于程序后台中调度及支持性工作。当非守护线程,也就是用户线程全部停止时,守护线程随之结束。setDaemon() 可将线程设置为守护线程。守护线程中若有finally,其内容不一定会执行,也就是不能依靠finally来确保执行关闭或清理资源。

    线程的就绪运行与阻塞

    线程从启动到结束的中间过程是怎样的?当线程所占有的CPU时间片到期时是如何等待下一个时间片?在线程运行中可能引发死锁等线程安全问题,可能被挂起等等,在这些情况下当前线程并不会释放占用的资源,此时线程是什么状态?线程的生命周期有新建,就绪,运行,阻塞,死亡5种状态。他们的联系如下:
    线程生命周期
    CPU时间片轮转,即使启用start(),当操作系统分配的CPU时间片未到的时候,线程也不会进入运行状态,而是就绪状态,等待时间片到达,获得执行权,才是运行状态。join() 方法可获取执行权,yield() 方法则会让出时间片。而sleep()wait() 会使线程进入阻塞状态。

    线程优先级
    优先级范围1~10,优先级越高,被分配CPU时间片的可能越高。setPriority() 可设置线程运行优先级。

    yield()、join()

    yield() 方法会让出时间片,将线程从运行状态转为就绪状态,等待时间片执行权。操作系统在选中下一个时间片分配对象时,仍可能选中该线程。调用yield()方法的线程并不会释放锁。
    join() 方法会将调用的线程对象加入到当前线程,挂起当前线程,至加入的线程执行完后继续,即在线程B中调用了线程A的join()方法,那么,直到线程A执行完毕后,才会继续执行线程B。也就是将两个交替执行的线程合并为顺序执行

    展开全文
  • JAVA对象的生成到终结

    2019-08-10 10:11:47
    的一生分为七个阶段:加载,验证,准备,解析,初始化,使用,卸载。 前面五个阶段是类加载过程,类加载过程有且只有一次。 加载的工作内容是使用类的全限定名来获取定义一个二进制字节流,定义一个Class对象...

    类的一生分为七个阶段:加载,验证,准备,解析,初始化,使用,卸载。

    前面五个阶段是类加载过程,类加载过程有且只有一次。

    加载的工作内容是使用类的全限定名来获取定义一个二进制字节流,定义一个Class对象(在HotSpot虚拟机之中,这个对象存储进了方法区)。

    验证的工作内容是为了确保字节流中的信息符合当前虚拟机的要求,并且不会伤害到虚拟机自身的安全。

    准备是设置类变量的初始值并为其在方法区分配空间的阶段,这里的初始化不是指将程序员设定的值赋进去,而是0值。

    解析是将符号引用换为直接引用。

    初始化是类加载的最后一个过程,赋值类变量,执行静态代码块,执行类构造器。

    可能会有疑惑,加载的时候创建了Class对象,可是静态变量分配空间是在准备阶段,难不成构造器是静态的码,这里请移步关于构造器是否是静态方法的讨论

    接下来就是平时真正创建对象的时候了,也就是我们的实例构造器或者说是构造方法了。

    一个对象的引用会创建在栈空间上,对象则会分配在堆内存上。这时候是如何分配内存的呢,不可能直接放进去就行了,分配内存的时候有两种分配方式。第一种假设是内存非常的规整,用过的放在一边,没有用过的放在另一边,中间有一个指针作为分界线,每当需要分配内存的时候指针就会偏移与对象大小相同空间的位置给他,这个是“指针碰撞”。第二种是使用过的内存和没有使用过的交叉存放,虚拟机会维护一个列表,等到有新的对象要进来的时候,就会找一个足够他使用的内存给他,这个是“空闲列表”。这是内存分配的过程。

     

    一个对象在内存中的布局由三个部分构成,对象头和实例数据还有对齐填充。

    对象头当中存放了运行时数据,例如哈希码,GC分代年龄等等,还有类型指针。

    实例数据是指存储的有效的信息,也就是在代码部分记录下来的信息,从父类中继承下来的,子类中定义的。

    对其填充不是必须存在的,HotSpot要求对象的起始地址必须是8字节的整数倍,也就是说对象必须是8字节的在整数倍,这时候对齐填充就会把不足的部分补全。

     

    对象分配内存的过程和结构部分说完了,那就说一下是如何查找这个对象的吧

    我们可以通过句柄访问和直接访问。

    1.句柄访问

    句柄访问会创建两个指针,一个是指向实例对象数据,一个指向对象类型数据。

    2.直接指针

    直接指针上创建了一个指针,指向对象类型数据。

    关于数据的移动,句柄访问是不需要修改reference的,但是直接指针会需要修改,也就是修改的时候只需要修改实例数据指针就可以了,修改起来比较方便。

    关于数据的访问,句柄访问需要定位两次指针,然而直接指针只需要定位一次,再创建了许多个对象之后,指定为一次指针所节省的开销还是非常大的。

    关于对象的消亡过程请移步对象存活状态的判定以及死亡过程

    参考书籍:《深入理解JAVA虚拟机》

     

    展开全文
  • 我正在尝试反序列化以下字符串,对于Java来说我是新手,我无法在我的一生中使用它…我现在仅尝试在对象中解码两个字符串.我的JSON和Java类如下.我得到的结果变量确定.{"result": "true","recentlyMarkedTerritories": ...
  • 一个对象的一生

    千次阅读 2019-12-22 17:35:39
    我是一个普通 Java 对象,我出生在 Eden 区,在 Eden 区我还看到和我长很像小兄弟,我们在 Eden 区中玩了挺长时间。 有一天,Eden 区中人实在是太多了,我就被迫去了 Survivor 区 “From” 区。 自从去...
  • Java对象创建过程

    2020-06-09 00:55:00
    Java中,一个对象只要被正确的实例化之后才能被使用,在对象实例化的时候,会先检查相关的类信息是否已经被加载并初始化,在类初始化完毕之后才会继续完成对象的实例化,类的一生主要经历加载、连接(验证、准备、...
  • 对象的生命周期还好理解,就像是人的一生,从出生、少年、青年、中年、老年、死亡; 关于对象,可达性可以理解为根据引用类型的不同而被分成了不同的可达等级。 该篇只是对生命周期和可达级别做一个了解,目的是...
  • 当我们学习过java基础语法后,那么重头戏来了,我们需要掌握大招,当我们全面了解java真正的核心思想后,一定会贯穿整个java开发人员的一生!面向对象:★★★★★(核心)特点:1:将复杂的事情简单化。2:面向对象将...
  • 会贯穿整个java开发人员的一生哦!面向对象:★★★★★(核心)特点:1:将复杂的事情简单化。2:面向对象将以前的过程中的执行者,变成了指挥者。3:面向对象这种思想是符合现在人们思考习惯的一种思想。过程和对象...
  • 2.调度指针函数需要知道每个存入数据具体存在时间,在java中因为这个特点,栈一般不用来存放对象 3.因为其速度快且先进后出运行模式,通常作为方法执行内存模型 4.方法调用时,开辟一个独立栈帧如main...
  • Java基础之面向对象

    2013-11-30 21:47:54
    会贯穿整个java开发人员的一生哦! 面向对象:★★★★★(核心) 特点: 1:将复杂的事情简单化。 2:面向对象将以前的过程中的执行者,变成了指挥者。 3:面向对象这种思想是符合现在人们思考习惯...
  •  在观看周志明先生《深入理解Java虚拟机》时,看到VM中垃圾回收算法。由于标记清除算法会参生大量不连续内存碎片,所以就由复制算法代替。由于书中讲解不是很深入,所以想深入理解该算法时搜索到这篇文章...
  • 我们有时候希望无论是否产生了对象或无论产生了多少对象的情况下,某些特定的数据在内存空间里只有一份,例如所有的中国人都有个国家名称,每一个中国人都共享这个国家名称,不必在每一个中国人的实例对象中都.
  • 该楼层疑似违规已被系统折叠隐藏此楼查看此楼发一下最近的笔记集合类的由来:对象用于封装特有数据,对象多了需要进行存储,如果对象的个数不确定就使用集合容器进行存储集合特点:用于存储对象的容器集合的长度是可...
  • 我将包含我的Name对象的ArrayList写入一个文件,然后检索到的ArrayList将被不同的活动用于同一目的 . 此对象是单独包中的单独类 . 我用ObjectOutputStream编写ArrayList,然后关闭FileOutpoutStream和...
  • JSP9大内置对象 request : 客户端提交给服务器的所有数据,都被封装在该对象中。 response: 服务器响应给客户端的所有数据,都被封装在该对象中。...人的一生: 从呱呱坠地开始,到百年以后结束,算一次人生会
  • 一、什么异常。二、如何处理异常-try-catch-finally-throw-throws-自定义...①使用空对象的引用调用方法。空指针异常。 ②数组越界 ③除数为0 这些都是运行期间错误产生的表现。 四、在程序运行过程中,意外发生的情...
  • 下面是由 整理 java 学习 计划希望对您有用 java 学习计划篇一计划一透彻理解面向对象 初学 Java 就像交朋友从陌生到熟悉再到铁杆搭档一生相伴随 着学习深入你会发现学 Java 并不是想象那样枯燥和困难甚 ...
  • 初学Java就像交朋友从陌生到熟悉再到铁杆搭档一生相伴,随着学习深入,你会发现学Java并不是想象那样枯燥和困难,以下小编为大家介绍下最有效率提高Java的10个计划,希望可以帮到初学者: 计划一:透彻理解面向...
  • 线程的一生–6个状态(Java) new runnable blocked waiting timed waiting terminated new状态 当Thread类的对象被创建出来,还没有执行start()方法时,此时处于new状态。 runnable状态 对象一旦调用start()方法,...
  • 一生要遇见太多人, 即使有些话字字诛心, 也没必要活在他们眼神里, 只要内心澄明, 就永远不用讨好一个不懂你人. 爱生活, 爱自己. 重写: 返回值类型、方法名、参数列表必须相同。子类重写方法...
  • 二、我这一生遇见所有人里,任他们多漂亮,都未及你矜贵。三、好东西喜欢跟人分享,但更好只想私藏,比如:你。四、恰到好处喜欢最舒服,你不用多好,我喜欢就好,我没有很好,你不嫌弃就好。五、你总说时间过...
  • 1、透彻理解面向对象初学Java就像交朋友从陌生到熟悉再到铁杆搭档一生相伴,随着学习深入,你会发现学Java并不是想象那样枯燥和困难,甚至还有一些美妙之感,这是在拥有强大技术和出色设计思想后才能体会...
  • 1.椅子大战(对象如何改变你的一生) 第一阶段: 要求:在图形接口画出四方形、圆形和三角形。当用户点选图形时,图形需要顺时针转360° 并依据形状的不同播放AIF音效文件。 1号人物:直接写出了 rotate 和 ...
  • 前篇当中,代码都放在main()里面,那根本不是面向对象的做法。 椅子大战(对象如何改变你的一生) 程序规格: 在图形接口画出四方形,圆形和三角形,当用户点选图形时,图形需要顺时针转360度并依据形状的不同...
  • 1、透彻理解面向对象初学Java就像交朋友从陌生到熟悉再到铁杆搭档一生相伴,随着学习深入,你会发现学Java并不是想象那样枯燥和困难,甚至还有一些美妙之感,这是在拥有强大技术和出色设计思想后才能体会...
  • 也许在古代,新婚之夜,透过这层薄纱,你看到或者是惊喜,或许是惊悚,不要怕,无论是惊悚还是惊喜,她都会伴你一生。 1 曾几何时?你还会在面试当中与面试官对答如流解释抽象类和接口吗? 面试官:解释一下...
  • 1、透彻理解面向对象初学Java就像交朋友从陌生到熟悉再到铁杆搭档一生相伴,随着学习深入,你会发现学Java并不是想象那样枯燥和困难,甚至还有一些美妙之感,这是在拥有强大技术和出色设计思想后才能体会...

空空如也

空空如也

1 2 3 4 5
收藏数 96
精华内容 38
热门标签
关键字:

java对象的一生

java 订阅