据我所知,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
}
}
我的问题:
st1
和st2
之间的区别是什么?{}
声明行中传递()
而不是b2
中的构造函数的参数?b5
和b6
的错误?答案 0 :(得分:4)
st1:它存储对变量st1中表示“Test”的对象的引用。
st2:这里创建了一个java.lang.String的新对象,但它是不必要的:它共享构造函数参数的值并复制哈希值。 (没用。)
b1,b2:这就是为数组初始化器定义语法的方式。如果你深入研究语法,可能是一个很好的理由。
一个简单的类型没有对象,因此没有新的理由或可能,它实现了类中的对象(严格来说不是类)。
答案 1 :(得分:4)
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对象位于堆内存中。
st2
不是调用构造函数,它只是初始化数组的语法。
{}
不是一个类;它是一个原始类型,因此没有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)
你实际上是在一个问几个问题,这很好。我会尽力回答这些问题。
这两个是不同的,因为一个在堆上声明一个新的String对象,一个只指向一个字符串文字。有关详情,请参阅此处:Why new keyword not needed for String
B2是原始类型的数组。使用{}。
您可能会收到错误,因为byte无法存储整数。
答案 5 :(得分:2)
st1
您正在使用位于堆上的String文字对象(如果它已经存在,则它将被创建)。
st2
您可能会在此创建两个对象,首先编写"Test"
您正在使用文字(可能会创建一个新对象),然后从中显式创建一个新的String对象。您不太可能需要使用String构造函数。
b1
您正在此处创建新字节数组,其中包含byte
个基元。但基本上使用句法糖意味着你不需要明确地写new byte[]
,因为这可以通过表达式的左侧来确定。
b2
仅与完整格式的b1
完全相同。
b3
您正在使用()
括号,就像调用构造函数一样。这不是数组分配的工作原理。 {}
大括号用于填充数组,并且没有简单数组的构造函数。所以,你实际上在说&#34;我的字节数组包含&#39; a&#39;和&#39;&#39;&#34;放在{}
括号之间。
b4
这很好,你告诉编译器你希望这个字节b4
代表值3。
b5
这是不正确的,因为您使用数组初始化语法并尝试构建&#39;一个原始的。 b5
不是数组,因此您无法使用{}
大括号进行初始化。
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对象之间的区别
如果我的应用程序将使用一些固定数量的字符串值,我将使用字符串文字以获得更好的性能。但如果我的应用程序在不同时间需要不同的字符串,我将使用&#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,这就是你不用原始数据类型的参数调用构造函数的原因。