The blank final field name may not have been initialized error - java

Following code is giving compilation error mentioned below at line 1
The blank final field name may not have been initialized
My question is why is this error there as i have already initialized field in its constructor.
public class Test1 {
private final String name;
public Test1() {
name = "abc";
}
#SuppressWarnings("rawtypes")
private final Function fs = n -> {
System.out.println(this.name);// Line 1
return n;
};
public static void main(String[] args) {
new Test1();
}
}

During object creation, instance initialisers (i.e. assignments to instance variables and initialisation blocks) get executed before a constructor runs and hence, they would need the values to be initialised by then. Following should work:
public class Test1 {
private final String name;
public Test1() {
name = "abc";
fs = n -> {
System.out.println(this.name);// Line 1
return n;
};
}
#SuppressWarnings("rawtypes")
private final Function fs;
public static void main(String[] args) {
new Test1();
}
}

Related

Do I avoid the risk of privacy leaks, if I set the instance variables to private?

I am working on a Java assignment. My professor wrote: Warning: Be sure to set the attributes of the Class in such a way to avoid the risk of any privacy leaks. I am getting confused with it. My understanding towards privacy leaks is always to use a copy constructor, but how can instance variables get privacy leaked? Is this why we always set instance variables to private?
Here is an Example in DemoClass variables are private which can not be accessed directly. You can only get these variables with getters and setters
public class DemoClass {
// you can not get these variable directly
private String stringValue;
private int integerValue;
public DemoClass(String stringValue, int integerValue) {
this.stringValue = stringValue;
this.integerValue = integerValue;
}
public void setStringValue(String stringValue) {
this.stringValue = stringValue;
}
public void setIntegerValue(int integerValue) {
this.integerValue = integerValue;
}
public String getStringValue() {
return stringValue;
}
public int getIntegerValue() {
return integerValue;
}
}
class Main {
public static void main(String[] args) {
DemoClass demoClass =new DemoClass("My String Value",120);
System.out.println(demoClass.getIntegerValue());
System.out.println(demoClass.getStringValue());
}
}
If this is your main code then the answer would be yes, that's why we set any variable except global variables to private.
class Demo {
private String Var = "100";
void Meth(String str) {
System.out.println(str + Var);
}
}
class Main {
public static void main(String[] args) {
Demo demo1 = new Demo();
demo1.Meth("10 x 10 = ");
System.out.println(demo1.Var);//Error. This variable is set to private so it cannot be accessed.
}
}
The privacy or control of your variables can only be accesed by the superclass/control block of the variable.

Trying to increment local variable from a separate method but not working. Confusion about Activation Stack/Record

public class Demo {
public static void main(String[] args){
Demo instance = new Demo();
instance.init();
}
public void init() {
int size = 0;
inc(size);
System.out.println(size);
}
public int inc(int size){
size++;
return size;
}
}
When I call the code above, the number zero is returned.
Even declaring size as a class attribute instead of a local variable does not solve the problem. I understand that when a method is complete, the corresponding record (containing local variable and such) is popped off of the activation stack. But, if the size variable is declared in the init() method, and then incremented and returned in a separate method (inc()), shouldn't size be equal to 1?
When incrementing you do not assign the value to anything, it increments it, but it does not store it anywhere so the value remains 0, try doing like this.
public class Demo
{
public static void main(String[] args)
{
Demo instance = new Demo();
instance.init();
}
public void init()
{
int size = 0;
size = inc(size);
System.out.println(size);
}
public int inc(int size)
{
size++;
return size;
}
}
or like this
public class Demo
{
public static void main(String[] args)
{
Demo instance = new Demo();
instance.init();
}
public void init()
{
int size = 0;
System.out.println(inc(size));
}
public int inc(int size)
{
size++;
return size;
}
}
size = inc(size);
will solve your problem, since you are not using a public scoped variable.
If you want to make this a bit elegant (at least I think this will be a bit more handy), then you need to declare a variable as a class variable.
I will illustrate this to you:
public class Demo {
int size; //global range variable
public static void main(String[] args){
Demo instance = new Demo();
instance.init();
}
public void init() {
this.size = 0;
inc();
System.out.println(this.size);
}
public void inc(){
this.size++; //will increment your variable evertime you call it
}
}

Is it possible to update a reference in a method?

I have asked this question here. I will try to make this one more specific.
class Example {
public static void main(String[] args) {
A a = null;
load(a);
System.out.println(a.toString());
// outcome is null pointer exception
}
private static void load(A a) {
a = new A();
}
}
class A {
public void String toString() {
return "Hello, world!"
}
}
So, does it possible to update a reference in a method? For some reason I need to do this. The reasons can be seen at above linked page.
Yes, it's possible if you define the parameter as A[] i.e. load(A[] a) and then in the method you update the element at position 0 in that array i.e. a[0] = new A(). Otherwise, it's not possible as Java is pass by value. I often use this workaround.
EXAMPLE 1:
class Example {
public static void main(String[] args) {
A[] a = new A[1];
a[0] = new A("outer");
System.out.println(a[0].toString());
load(a);
System.out.println(a[0].toString());
}
private static void load(A[] a) {
a[0] = new A("inner");
}
}
class A {
private String name;
public A(String nm){
name = nm;
}
public String toString() {
return "My name is: " + name;
}
}
EXAMPLE 2:
class Example {
public static void main(String[] args) {
A[] a = new A[1];
a[0] = null; // not needed, it is null anyway
load(a);
System.out.println(a[0].toString());
}
private static void load(A[] a) {
a[0] = new A("inner");
}
}
class A {
private String name;
public A(String nm){
name = nm;
}
public String toString() {
return "My name is: " + name;
}
}
NOTE: In fact, instead of an A[] you can use any wrapper object (an object which contains in itself a reference to an A object). The A[] a is just one such example. In this case a[0] is that reference to an A object. I just think that using an A[] is the easiest (most straightforward) way of achieving this.
As already pointed by other java is pass-by-value.You need something like pointer in C with the object location address so that you can modify that particular address value.As an alternate to pointer you can use array.Example
class Example {
public static void main(String[] args) {
A[] aArray=new A[1];
load(aArray);
System.out.println(aArray[0].toString());
// outcome is Hello, world!
}
private static void load(A[] aArray2) {
aArray2[0] = new A();
}
}
class A {
public String toString() {
return "Hello, world!";
}
}
You could just have:
public static void main(String[] args) {
A a = load();
}
private static A load() {
return new A();
}
No you can't.
In java everything is passed as value not as reference.
I came out with this. Perfectly satisfied my need and looks nice.
class A {
private A reference;
private String name;
public A() {
reference = this;
}
public void setReference(A ref) {
reference = ref;
}
public void setName(String name) {
reference.name = name;
}
public String getName() {
return reference.name;
}
}

Why can I not make an instance of a local Java class in side of a Java WebMethods Services?

I need to be able to create an instance of the following class in my web Services Method and for some reason there is an error.
Question: Why would I not be able to declare and instance of my class in my Java WEBServices?
**GetTheFileListClass FindArrayListOfFiles = new GetTheFileListClass(fileName);**
Error:
The source was saved, but was not compiled due to the following errors:
C:\SoftwareAG\IntegrationServer\packages\DssAccessBackup\code\source\DssAccessBackup\services\flow.java:48: non-static variable this cannot be referenced from a static context
GetTheFileListClass FindArrayListOfFiles = new GetTheFileListClass(fileName);
1 error
Code:
public final class ReturnListOfValidFileNames_SVC
{
/**
* The primary method for the Java service
*
* #param pipeline
* The IData pipeline
* #throws ServiceException
*/
public static final void ReturnListOfValidFileNames(IData pipeline)
throws ServiceException {
IDataCursor pipelineCursor = pipeline.getCursor();
String fileName = IDataUtil.getString(pipelineCursor,"FileName");
ArrayList<String> listOfFileName = new ArrayList<String>();
//This will get the file list and set it to the local parameter for the Service
**GetTheFileListClass FindArrayListOfFiles = new GetTheFileListClass(fileName);**
listOfFileName = FindArrayListOfFiles.getMyFileList();
IDataUtil.put( pipelineCursor,"ListOfFileNames",listOfFileName.toArray());
pipelineCursor.destroy();
}
// --- <<IS-BEGIN-SHARED-SOURCE-AREA>> ---
public class GetTheFileListClass {
String fileName = new String();
ArrayList<String> MyFileList = new ArrayList<String>();
String InputFile = new String();
GetTheFileListClass(String workFile){
setInputFile(workFile);
}
public void setMyFileList(ArrayList<String> myList, String newFileValueToAdd) {
myList.add(newFileValueToAdd);
}
public ArrayList<String> getMyFileList() {
return MyFileList;
}
public void setInputFile(String wFile) {
fileName = wFile;
}
public String getInputFile(){
return fileName;
}
private String returnFileName(String a) {
String matchEqualSign = "=";
String returnFile = new String();
int index = 0;
index = a.indexOf(matchEqualSign,index);
index++;
while (a.charAt(index) != ' ' && a.charAt(index) != -1) {
returnFile += a.charAt(index);
//System.out.println(returnFile);
index++;
}
return returnFile;
}
private void locatedFileName(String s, String FoundFile, ArrayList<String> myFileListParm) {
final String REGEX = ("(?i)\\./\\s+ADD\\s+NAME\\s*=");
Pattern validStringPattern = Pattern.compile(REGEX);
Matcher validRegMatch = validStringPattern.matcher(s);
boolean wasValidRegMatched = validRegMatch.find();
if (wasValidRegMatched) {
FoundFile = returnFileName(s); //OUTPUT variable should go here
setMyFileList(myFileListParm,FoundFile);
}
}
//This is the methods that needs to be called from the main method
private void testReadTextFile() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String FileLine = null;
while ((FileLine = reader.readLine()) != null) {
locatedFileName(FileLine,fileName,MyFileList); //test to see if the "./ Add name=" is found in any of the strings
}
}
private void printArrayFileList(ArrayList<String> myList) {
for (String myIndexFileListVariable : myList) {
System.out.println("File Name: " + myIndexFileListVariable);
}
}
}
// --- <<IS-END-SHARED-SOURCE-AREA>> ---
}
your inner class is not static, try
public static class GetTheFileListClass { ....
The rules of scope still apply, even though GetTheFileListClass is (a) a class and is (b) public. Because it is declared inside of ReturnListOfValidFileNames_SVC, that is its enclosing class, so any non-static reference to it must follow the rules of scope.
So you have two options (I'm using main to simulate your static method):
Declare the inner class static:
public final class Outer {
public static void main(String[] args) {
Inner inner = new Inner ();
inner.doIt();
}
public static class Inner {
public void doIt() {
System.out.println("Do it");
}
}
}
OR
Within your static method, create an instance of the enclosing class and use the new operator on it like this
public final class Outer {
public static void main(String[] args) {
Outer outer = new Outer();// Now we have an enclosing instance!
Inner inner = outer.new Inner ();
inner.doIt();
}
public class Inner {
public void doIt() {
System.out.println("Do it");
}
}
}
Have fun!

java - access incremented static variable from another class

I have a static variable and updating it's value in class. But when i access this variable from another class , it shows unupdated value.
CLASS A
public static int postID = 1;
public static String Creator()
{
String message = "POST id="+postID;
return message;
}
void updatePostID()
{
postID++; //this function is being called each 10 seconds
}
#Override
public void start() {
handler.post(show);
}
Handler handler = new Handler();
private final Runnable show = new Runnable(){
public void run(){
...
updatePostID();
handler.postDelayed(this, 10000);
}
};
CLASS B
String message = A.Creator(); //this always prints postID as 1 all time
I need a global variable that i can access from each class and update its value. Waiting for your help (I am using this with a Android Service)
this is a tested code .
public class A {
public static int id = 0;
public static int increment(){
return A.id++;
}
}
public class B {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
System.out.println(A.increment());
}
}
}
class A
{
static int id=0;
//I am updating id in my function ,
{
id++;
}
}
public class StartingPoint {
public static void main(String... args){
A a = new A();
A b = new A();
System.out.println(A.id);
System.out.println(a.id);
}
}
You need to call work to execute id++;
class B {
public static void main(String... args){
A a = new A();
a.work(); // You need to call it to apply add operation
System.out.println(A.id); // Prints 1
}
}
And this is a sample class A:
class A {
static int id = 0;
public void work(){
id++;
}
}
Save class A in a file named A.java and class B in a file named B.java.
Then compile B. Since B creates an instance of class A, A will be compiled and you don't need to compile A separately-
javac B.java
After compilation, to execute/run-
java B
Sajal Dutta's answer explains it perfectly, but if you want to keep it ALL static (i.e. not create any objects of class A, you could modify the code slightly to this:
class A {
static int id = 0;
public static void work(){
id++;
}
}
Then:
class B {
public static void main(String[] args){
System.out.println(A.id);
A.work();
System.out.println(A.id);
}
}
This would produce:
0
1
Edit (with regard to your updated question)
Where are you specifying the update of the static int? From the code you've provided all you will do is print out the same int over and over as the method containing the increment process is never called.
Edit 2:
Try this:
Change:
handler.post(show);
to:
handler.postDelayed(show, 10000);

Categories