stack overflow的好问题 - java篇

问题 & 答案

1.怎样交换一个字符串中的两个字段?

Q:问题描述:怎样交换 foo 和 bar 的位置?

String word1 = "bar";

String word2 = "foo";

String story = "Once upon a time, there was a foo and a bar."

解决办法:

1). 使用中间变量的方式。

story = story.replace("foo", "lala");

story = story.replace("bar", "foo");

story = story.replace("lala", "bar");

弊端:需要保证作为中间变量的字符串没有出现过;本来只需要进行一次交换,但这个方法进行了三次操作!

2). 使用StringUtils工具类方法

StringUtils.replaceEach(story, new String[]{"foo", "bar"}, new String[]{"bar", "foo"})

 2.一个Java类中,只定义变量,没有赋值,会消耗内存么?

A:会。即使没有赋值,也会有默认值。例如int i;和int i=0;的效果是一样的。

对于定义在方法内部的局部变量,没有给出明确答案。有人给出这样的代码:

public static void main(String[] args) {

    int i;  // ignored

    int j = 5;

    String s = "abc";

    String sNull; // ignored

}

二进制代码:

  LocalVariableTable:

        Start  Length  Slot  Name   Signature

            0       6     0  args   [Ljava/lang/String;

            2       4     2     j   I

            5       1     3     s   Ljava/lang/String;

   }

jvm忽略了i,sNull,所以有人认为方法内部没有赋值的局部变量不消耗内存;

但是,也有人认为,slot 只列出了0,2,3位置,而没有列出slot 1,而这个位置,正是给i留出来的。所以,他认为消耗内存。

 3.在构造器中调用可覆写方法,有什么错误?

首先明确一点,这种调用方法不一定报错,某些严格要求的IDE会给出warning.

public class ConstructorMethod {

    abstract static class Base{

        Base(){

            info();

            System.out.println("base class constructor running");

        }

        abstract void info();

    }

    static class Son extends Base{

        public void info(){

            System.out.println("Son class method running");

        }

        Son(){

            super();

            System.out.println("son class constructor running");

        }

    }

    public static void main(String[] args) {

        Son s=new Son();

        /*Son class method running

        * base class constructor running

        * son class constructor running

        * Son类的方法在Son对象未创立之前就被调用了*/

    }

}

上面的例子,可以通过编译、运行,但是在一些情况下,构造器里有可覆写的方法,可能引发异常:

public class ConstructorMethod2 {

    abstract static class A{

        private A a;

        A(){

            add(a);//注释掉这一行,可以消除空指针异常

        }

        abstract void add(A a);

    }

    static class B extends A{

        List<A> bList=new ArrayList<A>();

        private B b;

        B(){

        }

        void add(A a){

            bList.add(b);

        }

    }

    public static void main(String[] args) {

        B b=new B();

    }

}

上面的例子,引发了空指针异常:java.lang.NullPointerException。

总之,构造器中尽量不要调用可覆写方法的原因是:我们不知道子类会去怎样实现这些方法!

4.java中,数组也是对象,但为什么数组对象不是基于某个类?

比如说,有一个类为User,如果我创建了一个User[]users的对象,我却不能为User[]这个类重写toString()方法。为什么java不能够创建数组类?
答:数组不是作为某个类的实例。如果数组作为某个类的实例的话,那么有一点好处:我们可以为这个数组重写不少方法,例如toString,equals等,但是,这点好处不足以抵消它的坏处——增加了写代码的复杂程度。

5.java中静态代码块的作用

public class LanguageBean implements Serializable{

    private static Map<String,Object> countries;

    static{

        countries = new LinkedHashMap<String,Object>();

        countries.put("English", Locale.ENGLISH); //label, value

        countries.put("Chinese", Locale.SIMPLIFIED_CHINESE);

    }

}

静态代码块、非静态初始化代码块、构造函数,三者是执行顺序是静态代码块>>非静态初始化代码块>>构造函数。
无论是静态还是非静态,其运行顺序都先于构造函数。静态初始化代码块只在初始化类的时候执行一次,非静态在每次创造对象的时候都会执行

来自:

1.How can I replace two strings in a way that one does not end up replacing the other?

2.Do unused local variables in a method acquire memory in JVM?

3.What's wrong with overridable method calls in constructors?

4.why-are-arrays-objects-but-can-not-be-used-as-a-base-class

5.static-method-with-static-default-code

你可能感兴趣的:(overflow)