当我们被允许使用" new" Java中的关键字以及如何使用它?

时间:2016-04-23 06:38:24

标签: java

据我所知,new关键字用于实例化类。我认为我们需要调用类构造函数并在此关键字后传递其参数。 从右

好的,这是一段代码:

public class JavaApp{

    public static void main(String[] args) {
        String st1 = "Test";
        String st2 = new String("Test");

        byte[] b1 = {'a', 'b'};
        byte[] b2 = new byte[]{'a', 'b'};
        byte[] b3 = new byte[]('a','b'); //Error

        byte b4 = 3;
        byte b5 = new byte{3}; //Error
        byte b6 = new byte(3); //Error

    }

}

我的问题:

  1. st1st2之间的区别是什么?
  2. 为什么我们必须在{}声明行中传递()而不是b2中的构造函数的参数?
  3. 为什么我收到b5b6的错误?

9 个答案:

答案 0 :(得分:4)

st1:它存储对变量st1中表示“Test”的对象的引用。

st2:这里创建了一个java.lang.String的新对象,但它是不必要的:它共享构造函数参数的值并复制哈希值。 (没用。)

b1,b2:这就是为数组初始化器定义语法的方式。如果你深入研究语法,可能是一个很好的理由。

一个简单的类型没有对象,因此没有新的理由或可能,它实现了类中的对象(严格来说不是类)。

答案 1 :(得分:4)

  1. example- erlc -I /opt/ejabberd-16.03/lib/ejabberd-16.03/include -o /opt/ejabberd-16.03/lib/ejabberd-16.03/ebin ejabberd_src/ejabberd_c2s.erl st1是两个不同的对象;第一个位于 String-Pool 内,第二个位于普通java对象位于内存中。

  2. st2不是调用构造函数,它只是初始化数组的语法。

  3. {}不是一个类;它是一个原始类型,因此没有byte的构造函数。

答案 2 :(得分:3)

你的第一个答案可以在构造函数String(String)

的JavaDoc中找到
<script type = "text/javascript">
     function RadioCheck(rb) {
        var gv = document.getElementById("<%=Docgrid.ClientID%>");
        var rbs = gv.getElementsByTagName("input");

        var row = rb.parentNode.parentNode;
        for (var i = 0; i < rbs.length; i++) {
            if (rbs[i].type == "radio") {
                if (rbs[i].checked && rbs[i] != rb) {
                    rbs[i].checked = false;
                    break;
                }
            }
        }
    }    
</script>

第二个问题,这些是基元数组,你没有按照你所说的/** * Initializes a newly created {@code String} object so that it represents * the same sequence of characters as the argument; in other words, the * newly created string is a copy of the argument string. Unless an * explicit copy of {@code original} is needed, use of this constructor is * unnecessary since Strings are immutable. * * @param original * A {@code String} */ 调用“构造函数”。括号表示法只是一个初始化程序,它接受Java用于填充数组的值列表。 new Horse("Alan")概念在Java语言中根本就不存在,就像您认为的那样。

new byte[]()

第3个问题,byte不是一个对象,它是一个原语,它没有构造函数可以调用。

byte[] b2 = new byte[]{'a', 'b'};
byte[] b3 = new byte[]('a','b'); //Error

但是你可以使用Byte对象包装器,本质上是字节原语的Object版本,它有一个构造函数。

byte b5 = new byte{3}; //Error
byte b6 = new byte(3); //Error

答案 3 :(得分:2)

在st1中,您创建一个表示字符串“Test”的String对象,在st2将String对象传递给String构造函数。 String构造函数可以使用多种参数,如果将String传递给它,它只是复制一个。但是,它也可以执行诸如将char数组转换为String之类的操作。

b3给出了一个错误,因为那只是不正确的语法,在创建时定义数组的值,正确的语法是b2中的括号。

对于b5,我真的没有得到你想要做的事情,这种语法对我来说没有意义。

对于b6,不可能使用构造函数创建一个字节,因为构造函数与对象相关,而byte是基本类型而不是对象。如果你输入Byte而不是你可以这样做,因为Byte是一个字节的对象包装版本。 (同样适用于其他原始数据类型,double&amp; Double,boolean&amp; Boolean,char&amp; Character等。)

答案 4 :(得分:2)

你实际上是在一个问几个问题,这很好。我会尽力回答这些问题。

  1. 这两个是不同的,因为一个在堆上声明一个新的String对象,一个只指向一个字符串文字。有关详情,请参阅此处:Why new keyword not needed for String

  2. B2是原始类型的数组。使用{}。

  3. 在创建时初始化数组
  4. 您可能会收到错误,因为byte无法存储整数。

答案 5 :(得分:2)

  1. st1您正在使用位于堆上的String文字对象(如果它已经存在,则它将被创建)。

  2. st2您可能会在此创建两个对象,首先编写"Test"您正在使用文字(可能会创建一个新对象),然后从中显式创建一个新的String对象。您不太可能需要使用String构造函数。

  3. b1您正在此处创建字节数组,其中包含byte个基元。但基本上使用句法糖意味着你不需要明确地写new byte[],因为这可以通过表达式的左侧来确定。

  4. b2仅与完整格式的b1完全相同。

  5. b3您正在使用()括号,就像调用构造函数一样。这不是数组分配的工作原理。 {}大括号用于填充数组,并且没有简单数组的构造函数。所以,你实际上在说&#34;我的字节数组包含&#39; a&#39;和&#39;&#39;&#34;放在{}括号之间。

  6. b4这很好,你告诉编译器你希望这个字节b4代表值3。

  7. b5这是不正确的,因为您使用数组初始化语法并尝试构建&#39;一个原始的。 b5不是数组,因此您无法使用{}大括号进行初始化。

  8. b6在这里,您尝试在原语上调用构造函数。基元没有构造函数,因此您不需要 new 它们,也不需要将参数传递给任何构造函数。您只需为它们指定值即可。

答案 6 :(得分:2)

在高级别都是String对象,但主要区别在于new()运算符总是创建一个新的String对象。此外,当您使用文字创建字符串时,它们将被实现。当您比较使用String literal和new运算符创建的两个String对象时,这将更加清晰,如下例所示:

String a = "Java";     
String b = "Java";    
System.out.println(a == b);  // True    

这里创建了两个不同的对象,它们有不同的引用:

String c = new String("Java");    
String d = new String("Java");      
System.out.println(c == d);  // False    

类似地,当您将String文字与使用new()运算符使用==运算符创建的String对象进行比较时,它将返回false,如下所示:

String e = "JDK";        
String f =  new String("JDK");        
System.out.println(e == f);  // False        

String literal和String对象之间的区别

enter image description here
如果我的应用程序将使用一些固定数量的字符串值,我将使用字符串文字以获得更好的性能。但如果我的应用程序在不同时间需要不同的字符串,我将使用&#39; new&#39;运营商来创建它们。

答案 7 :(得分:1)

让我们清楚一些关于java中的原语和非原语的东西,这是理解答案所必需的。

  • String是一个类,不是原始数据类型(只有byte,short,int,long,double,boolean,float和char是原语)。

  • 内存在堆栈中用于基本类型,在中用于 非原始类型。

  • 字符串是一种特殊类型。我们可以在堆中创建字符串(它表现为非基元)以及 stack(它表现为原语)。

  • new (调用构造函数并在堆中创建对象)关键字仅适用于非基本类型(如堆中的字符串)但 原始类型不需要(例如&#39; int&#39;)。

回答第一个问题:

String st2 = new String("Test");

在上面的行中,您将在堆中创建字符串对象。由于它是非原始的,因此总是需要 new 来为堆中的字符串创建对象。

然后你可能会想,&#34;那么我如何在这一行中没有 new 关键字创建字符串对象?&#34;

 String st1 = "Test";

这里你没有在堆中创建字符串对象。您正在堆栈中创建一个字符串文字,其行为类似于基本类型。 回答第3个问题:

byte 是原始数据类型,因此您不应使用 new 来创建字节,否则您将面临错误。

byte b=new byte(4); //error

你在想,&#34;那么为什么它没有在这一行中抛出错误?&#34;

byte[] b2 = new byte[]{'a', 'b'};

它没有抛出错误,因为你没有在这里用 new 创建一个字节对象。 您正在创建一个数组,就像引用堆中其他对象的引用对象一样。

Array是非原始的,因此您必须使用 new

回答第二个问题:

  

2.为什么我们必须在{}而不是()中传递构造函数的参数,在b2声明行中?

这里,您没有将参数传递给构造函数。您正在使用某些值初始化数组。

数组初始化应使用{}但不能使用()。因此错误

 byte[] b3 = new byte[]('a','b'); //Error

答案 8 :(得分:0)

new关键字用于创建特定类的对象。使用'='运算符进行运算符重载。正如我们在撰写String st1="Test";时所做的那样与String st2=new String("Test");完成相同的事情。除了运算符重载之外,两个语句之间没有任何差别。 在b1和b2的情况下。创建了一个对象数组,因此我们需要使用{}来传递多个值。对于调用构造函数,我们总是使用()括号而不是花括号。这就是b5中出现错误的原因。在b6和b5的情况下,你得到了错误,因为byte是原始数据类型,其包装类是Byte,这就是你不用原始数据类型的参数调用构造函数的原因。