Java基础之基础问题

2018-11-15  本文已影响0人  KD小帅

1. String类

请说下String与StringBuffer区别,String类可以被继承吗,为什么?String为什么要设计成不可变的?

答:在这方面运行速度快慢为:StringBuilder > StringBuffer > String,因为String是字符串常量,创建之后不可更改,StringBuffer是字符串变量,可以更改。在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的。如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。

不能被继承,因为Sting是这样定义的:public final class String extends Object,里边有final关键字。

因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享,这样便不用因为线程安全问题而使用同步,字符串自己便是线程安全的;因为字符串是不可变的所以在它创建的时候 hashcode 就被缓存了,不变性也保证了 hash 码的唯一性,不需要重新计算,这就使得字符串很适合作为 Map 的键,字符串的处理速度要快过其它的键对象,这就是 HashMap 中的键往往都使用字符串的原因。

String类可以new出来吗?String s1=new String("abc")在内存创建了几个对象?

答:可以,2个,String s1把变量放到常量池里,new String("abc")把变量放到内存里。

2.基本类型

Java中int、char、long各占多少字节数?

答:Java中8大基本数据类型:整数型:byte --1比特位,在java中算1个字节;short--2个字节;int--4字节;long--8个字节;浮点型:float单精度--4个字节; double双精度--8个字节;字符型 char--1个字节 

一个int变量,用volatile修饰,多线程去操作++,线程安全吗?那如何才能保证i++线程安全?不用锁如何保证int自增安全?

答:不安全,因为volatile不能保证原子性,而i++其实有三步操作,读,修改,写,并不是原子操作,所以volatile当然不能保证结果的准确性。

保证i++线程安全

int 和 Integer 有什么区别?

答:1、Integer是int的包装类,int则是java的一种基本数据类型

2、Integer变量必须实例化后才能使用,而int变量不需要

3、Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值

4、Integer的默认值是null,int的默认值是0

char 型变量中能不能存贮一个中文汉字,为什么?

答:char类型可以存储一个中文汉字,因为Java中使用的编码是Unicode(不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一的唯一方法),一个char类型占2个字节(16比特),所以放一个中文是没问题的。

将 int 强制转换为 byte 类型的变量吗?如果该值大于 byte 类型的范围,将会出现什么现象?

答:是的,我们可以做强制转换,但是 Java 中 int 是 32 位的,而 byte 是 8 位的,所以,如果强制转化是,int 类型的高 24 位将会被丢弃,byte 类型的范围是从 -128 到 128。

3.泛型

什么是泛型,泛型主要有哪些应用场景

答:Java从1.5之后支持泛型,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

4.其他

静态属性和静态方法是否可以被继承?是否可以被重写?以及原因?

答:父类的静态属性和方法可以被子类继承。当父类的引用指向子类时,使用对象调用静态方法或者静态变量,是调用的父类中的方法或者变量。并没有被子类改写。static修饰函数/变量时,其实是全局函数/变量,它只是因为java强调对象的引用,它与任何类都没有关系。靠这个类的好处就是这个类的成员函数调用static方法不用带类名。注意:static关键字可以用修饰代码块.static代码块可以置于类中的任何一个位置,并可以有多个static代码块。在类初次被加载时,会按照静态代码块的顺序来执行,并且只会执行一次。

什么是内部类?内部类的作用有哪些?静态内部类的设计意图,成员内部类、静态内部类、局部内部类和匿名内部类的理解,以及项目中的应用?

答:内部类:在类的内部定义另一个类。

public class 外部类的名称{

    //外部类的成员

        publicclass 内部类的名称{

            //内部类的成员    }

}

使用内部类有什么好处;

1)实现多重继承; 

2)内部类可以很好的实现隐藏:一般的非内部类,是不允许有 private 与protected权限的,但内部类可以

3)减少了类文件编译后的产生的字节码文件的大小

使用内部类的缺点:使程序结构不清楚。

成员内部类也叫实例内部类。应用场合:每一个外部类对象都需要一个内部类的实例,内部类离不开外部类存在(相当于心脏对人体)。

/* * 成员内部类

*/public class Body {

    String arm;

    String leg;

    String blood;

    public Body(String arm, String leg, String blood) {

        super();

        this.arm = arm;

        this.leg = leg;

        this.blood = blood;

    }

    //内部类Heart

        class Heart{

                String name;

                 void work() {

                  System.out.println("心脏正在给"+arm+leg+"输"+blood);

        }

    };}

1、内部类如果使用static声明,则此内部类就称为静态内部类。(其实也相当于外部类)可以通过外部类. 内部类来访问。

2、静态内部类使用场合:内部类不需要外部类的实例(注意区分成员内部类),静态内部类存在仅仅为外部类提供服务或者逻辑上属于外部类,且逻辑上可以单独存在。

3、静态内部类的特征:

静态内部类不会持有外部类的引用

静态内部类可以访问外部的静态变量,如果访问外部类的成员变量必须通过外部类的实例访问

4、Java中只有内部类才可以是静态的

/* * 静态内部

*/public class Company {

    String companyNam;

    static String country;

    static class Clear{

        String name;

        public Clear() {

            // TODO Auto-generated constructor stub        }

        public Clear(String name) {

            super();

            this.name = name;

        }

        public void work(String name){

            String na=newCompany().companyNam="联想";

            country="中国";

            System.out.println(name+"为"+na+"打扫卫生,该公司属于"+country);

        }

    }

}

1、局部内部类也叫区域内嵌类,局部内部类与成员内部类类似,不过,区域内嵌类是定义在一个方法中的内嵌类。

2、使用场合:如果内部类对象仅仅为外部类的某个方法使用,使用局部内部类

3、特征:

用在方法内部,作用范围仅限于该方法中

根据情况决定持有外部类对象引用

不能使用private,protected,public修饰符

不能包含静态成员

/*

* 局部内部类

*/

public class School {

    String schoolName;

    String buss="培养人才";

    int studentNum;

    public School() {

        // TODO Auto-generated constructor stub

    }

    public School(String schoolName, String buss, int studentNum) {

        super();

        this.schoolName = schoolName;

        this.buss = buss;

        this.studentNum = studentNum;

    }

    //宣传

    public void show(){

        final double tvMoney=10000;

        final double netMoney=20000;

        class AdverTeam{

            String teamName="shen_hua";

            //电视宣传

            public void tvShow(){

                System.out.println("宣传队是:"+teamName);

                System.out.println("这是电视宣传,学校名称"+schoolName+",业务内容:"+buss+",学校人数:"+studentNum+",宣传所需费用"+tvMoney);

            }

            //网络宣传

            public void netShow(){

                System.out.println("宣传队是:"+teamName);

                System.out.println("这是网络宣传,学校名称"+schoolName+",业务内容:"+buss+",学校人数:"+studentNum+",宣传所需费用"+netMoney);

            }

        }

        new AdverTeam().tvShow();

        new AdverTeam().netShow();

    }

}

1、如果一个内部类在整个操作中只使用一次的话,就可以定义为匿名内部类。匿名内部类也就是没有名字的内部类,这是java为了方便我们编写程序而设计的一个机制,因为有时候有的内部类只需要创建一个它的对象就可以了,以后再不会用到这个类,这时候使用匿名内部类就比较合适。

2、使用场合:简化内部类的使用

3、特征:

使用new创建 ,没有具体位置

创建的匿名类,默认继承或实现new后面的类型

根据使用情况决定是否持有外部类对象引用

内嵌匿名类编译后生成的.class文件的命名方式是”外部类名称$编号.class”,编号为1,2,3…n,编号为x的文件对应的就是第x个匿名类

/* * 匿名内部类

*/public interface Person {

    public void run();

}

/* * 测试类

*/public class Test {

    public staticvoid main(String[] args) {

        Person p=new Person() {       

            publicvoid run() {

                System.out.println("匿名内部类实现的");

            }

        };

        p.run();

    }

}

final修饰一个对象,能否调用对象修改属性的方法

答:对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。

final, finally, finalize 的区别?

答:final修饰符(关键字)。被final修饰的类,就意味着不能再派生出新的子类,不能作为父类而被子类继承。因此一个类不能既被abstract声明,又被final声明。将变量或方法声明为final,可以保证他们在使用的过程中不被修改。被声明为final的变量必须在声明时给出变量的初始值,而在以后的引用中只能读取。被final声明的方法也同样只能使用,即不能方法重写。

finally是在异常处理时提供finally块来执行任何清除操作。不管有没有异常被抛出、捕获,finally块都会被执行。try块中的内容是在无异常时执行到结束。catch块中的内容,是在try块内容发生catch所声明的异常时,跳转到catch块中执行。finally块则是无论异常是否发生,都会执行finally块的内容,所以在代码逻辑中有需要无论发生什么都必须执行的代码,就可以放在finally块中。

finalize是方法名。java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者被执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。

try {}里有一个 return 语句,那么紧跟在这个 try 后的 finally {}里的 code 会不会被执行,什么时候被执行,在 return 前还是后?

答:1、尽管try{}中由return语句,但是finally中代码依旧会执行。

2、finally是在return中间执行的,也就是说,try{}中的return会先开始执行,在return执行的过程中,finally{}中的代码开始执行,并且比return先执行完毕

静态代码块什么时候执行?它的用途主要是做什么用的?它和构造方法哪一个先执行?

答:静态代码块在加载类时执行,当静态代码块的有多个时,执行顺序依照静态代码出现的先后顺序。(当然类只加载一次,所以静态代码块在程序的生命周期中也只执行一次)

非静态代码块在创建对象时执行(不必创建引用变量),且在构造函数前执行。(具体的原因可以参考李刚老师的“疯狂Java程序员的基本修养”一书)

总体上看,三者的执行顺序为:静态代码块 ——>非静态代码块——>构造函数。

作用

静态代码块主要就是在加载的时候执行,而且只执行一次,有唯一性,写在构造器中没有太大意义,例如jvm 

加载HibernateUtil类时,只执行一次,获取一个sessionFactory实例

非静态代码块,个人感觉没什么用,也可放到构造函数方法体的前面部分,得到同样的效果。

构造函数用于实例化对象时,初始化一些必要信息。如创建一个复杂的窗体界面可以放在构造函数中。

上一篇下一篇

猜你喜欢

热点阅读